Comment utiliser LINQ Contains (string[]) au lieu de Contains (string)

j'ai une grande question.

j'ai obtenu une requête linq pour le mettre ressemble tout simplement à ceci:

from xx in table
where xx.uid.ToString().Contains(string[])
select xx

les valeurs du tableau string[] seraient des nombres comme (1,45,20,10,etc...)

la valeur par défaut pour .Contains est .Contains(string) .

j'en ai besoin pour faire ceci à la place: .Contains(string[]) ...

modifier: un utilisateur a suggéré d'écrire une classe d'extension pour string[] . J'aimerais savoir comment, mais quelqu'un est-il prêt à m'indiquer la bonne direction?

EDIT : L'uid serait également un certain nombre. C'est pourquoi il est converti en chaîne de caractères.

aider quelqu'un?

81
demandé sur Otiel 2008-10-12 05:14:30

20 réponses

spoulson a presque raison, mais vous devez créer un List<string> de string[] d'abord. En fait un List<int> serait mieux si uid est aussi int . List<T> prend en charge Contains() . Faire uid.ToString().Contains(string[]) impliquerait que l'uid comme chaîne contient toutes les valeurs du tableau comme substrat??? Même si vous n'écrivez la méthode d'extension le sens qu'elle serait une erreur.

[MODIFIER]

à moins que vous ne le changiez et que vous ne l'écriviez pour string[] comme le démontre Mitch Wheat, alors vous pourriez sauter l'étape de conversion.

[ENDEDIT]

voici ce que vous voulez, si vous ne faites pas la méthode d'extension (à moins que vous ayez déjà la collection d'UID potentiels comme ints -- alors il suffit d'utiliser List<int>() à la place). Cela utilise la syntaxe de la méthode enchaînée, qui je pense est plus propre, et l' conversion en int pour s'assurer que la requête peut être utilisée avec plus de fournisseurs.

var uids = arrayofuids.Select(id => int.Parse(id)).ToList();

var selected = table.Where(t => uids.Contains(t.uid));
70
répondu tvanfosson 2015-02-04 05:35:04

si vous cherchez vraiment à répliquer contient , mais pour un tableau, voici un méthode d'extension et un exemple de code d'utilisation:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ContainsAnyThingy
{
    class Program
    {
        static void Main(string[] args)
        {
            string testValue = "123345789";

            //will print true
            Console.WriteLine(testValue.ContainsAny("123", "987", "554")); 

            //but so will this also print true
            Console.WriteLine(testValue.ContainsAny("1", "987", "554"));
            Console.ReadKey();

        }
    }

    public static class StringExtensions
    {
        public static bool ContainsAny(this string str, params string[] values)
        {
            if (!string.IsNullOrEmpty(str) || values.Length > 0)
            {
                foreach (string value in values)
                {
                    if(str.Contains(value))
                        return true;
                }
            }

            return false;
        }
    }
}
31
répondu Jason Jackson 2010-06-18 23:58:02

essayez ce qui suit.

string input = "someString";
string[] toSearchFor = GetSearchStrings();
var containsAll = toSearchFor.All(x => input.Contains(x));
17
répondu JaredPar 2010-08-31 18:00:10

LINQ in .NET 4.0 a une autre option pour vous; le .Toute méthode ();

string[] values = new[] { "1", "2", "3" };
string data = "some string 1";
bool containsAny = values.Any(data.Contains);
15
répondu RJ Lohan 2012-03-14 22:40:46

ou si vous avez déjà les données dans une liste et préférez l'autre format Linq:)

List<string> uids = new List<string>(){"1", "45", "20", "10"};
List<user> table = GetDataFromSomewhere();

List<user> newTable = table.Where(xx => uids.Contains(xx.uid)).ToList();
5
répondu JumpingJezza 2011-04-28 03:31:53

Que Diriez-vous de:

from xx in table
where stringarray.Contains(xx.uid.ToString())
select xx
3
répondu spoulson 2008-10-12 01:24:42

ceci est un exemple d'une façon d'écrire une méthode d'extension (note: Je ne l'utiliserais pas pour de très grands tableaux; une autre structure de données serait plus appropriée...):

namespace StringExtensionMethods
{
    public static class StringExtension
    {
        public static bool Contains(this string[] stringarray, string pat)
        {
            bool result = false;

            foreach (string s in stringarray)
            {
                if (s == pat)
                {
                    result = true;
                    break;
                }
            }

            return result;
        }
    }
}
2
répondu Mitch Wheat 2008-10-12 01:54:24

C'est une réponse tardive, mais je crois qu'elle est encore utile .

J'ai créé le NinjaNye .SearchExtension paquet nuget qui peut aider à résoudre ce problème même.:

string[] terms = new[]{"search", "term", "collection"};
var result = context.Table.Search(terms, x => x.Name);

vous pouvez également rechercher des propriétés à chaînes multiples

var result = context.Table.Search(terms, x => x.Name, p.Description);

ou effectuer un RankedSearch qui retourne IQueryable<IRanked<T>> qui comprend simplement une propriété qui montre combien de fois les termes de recherche sont apparus:

//Perform search and rank results by the most hits
var result = context.Table.RankedSearch(terms, x => x.Name, x.Description)
                     .OrderByDescending(r = r.Hits);

Il ya un guide plus complet sur les projets GitHub page: https://github.com/ninjanye/SearchExtensions

Espérons que cela aide les visiteurs à venir

2
répondu NinjaNye 2014-02-13 09:07:50

je crois que vous pourriez aussi faire quelque chose comme cela.

from xx in table
where (from yy in string[] 
       select yy).Contains(xx.uid.ToString())
select xx
1
répondu ctrlShiftBryan 2008-10-12 01:59:43

Linq méthode d'extension. Fonctionnera avec n'importe quel objet IEnumerable:

    public static bool ContainsAny<T>(this IEnumerable<T> Collection, IEnumerable<T> Values)
    {
        return Collection.Any(x=> Values.Contains(x));
    }

Utilisation:

string[] Array1 = {"1", "2"};
string[] Array2 = {"2", "4"};

bool Array2ItemsInArray1 = List1.ContainsAny(List2);
1
répondu kravits88 2014-04-17 04:34:02

est-ce que je suppose correctement que uid est un identifiant Unique (Guid)? Est-ce juste un exemple d'un scénario possible ou essayez-vous vraiment de trouver un guid qui correspond à un tableau de cordes?

Si cela est vrai, vous pouvez vraiment repenser toute cette approche, cela semble être une très mauvaise idée. Vous devriez probablement essayer de faire correspondre un Guid à un Guid

Guid id = new Guid(uid);
var query = from xx in table
            where xx.uid == id
            select xx;

honnêtement, je ne peux pas imaginer un scénario où l'appariement d'un réseau de cordes utiliser "contains" au contenu d'un guide serait une bonne idée. Pour une chose, Contains () ne garantira pas l'ordre des nombres dans le Guid de sorte que vous pouvez potentiellement faire correspondre plusieurs éléments. Sans parler de comparer les guids de cette façon serait beaucoup plus lent que juste le faire directement.

0
répondu justin.m.chase 2008-10-12 16:38:52

vous devriez l'écrire dans l'autre sens, en vérifiant votre liste d'ID utilisateur privilégié contient l'id sur cette rangée de la table:

string[] search = new string[] { "2", "3" };
var result = from x in xx where search.Contains(x.uid.ToString()) select x;

LINQ se comporte ici très lumineux et le convertit en un bon énoncé SQL:

sp_executesql N'SELECT [t0].[uid]
FROM [dbo].[xx] AS [t0]
WHERE (CONVERT(NVarChar,[t0].[uid]))
IN (@p0, @p1)',N'@p0 nvarchar(1),
@p1 nvarchar(1)',@p0=N'2',@p1=N'3'

qui incorpore basicly le contenu du tableau 'search' dans la requête sql, et fait le filtrage avec le mot-clé 'IN' dans SQL.

0
répondu Gorkem Pacaci 2009-01-19 05:31:20

j'ai réussi à trouver une solution, mais pas une grande car elle nécessite l'utilisation AsEnumerable() qui va retourner tous les résultats de la DB, heureusement que je n'ai que 1K enregistrements dans la table de sorte qu'il n'est pas vraiment perceptible, mais voilà.

var users = from u in (from u in ctx.Users
                       where u.Mod_Status != "D"
                       select u).AsEnumerable()
            where ar.All(n => u.FullName.IndexOf(n,
                        StringComparison.InvariantCultureIgnoreCase) >= 0)
            select u;

Mon post original suit:

Comment faites-vous l'inverse? Je veux faire quelque chose comme ce qui suit dans entité Framework.

string[] search = new string[] { "John", "Doe" };
var users = from u in ctx.Users
            from s in search
           where u.FullName.Contains(s)
          select u;

ce que je veux est de trouver tous les utilisateurs où leur Nom complet contient tous les éléments de la "recherche". J'ai essayé un certain nombre de façons différentes, qui toutes n'ont pas été de travailler pour moi.

j'ai aussi essayé

var users = from u in ctx.Users select u;
foreach (string s in search) {
    users = users.Where(u => u.FullName.Contains(s));
}

cette version ne trouve que ceux qui contenir le dernier élément de la recherche tableau.

0
répondu Brett Ryan 2009-07-17 10:03:00

la meilleure solution que j'ai trouvé était d'aller de L'avant et de créer une fonction de valeur de Table en SQL qui produit les résultats, tels que:

CREATE function [dbo].[getMatches](@textStr nvarchar(50)) returns @MatchTbl table(
Fullname nvarchar(50) null,
ID nvarchar(50) null
)
as begin
declare @SearchStr nvarchar(50);
set @SearchStr = '%' + @textStr + '%';
insert into @MatchTbl 
select (LName + ', ' + FName + ' ' + MName) AS FullName, ID = ID from employees where LName like @SearchStr;
return;
end

GO

select * from dbo.getMatches('j')

ensuite, vous faites simplement glisser la fonction dans votre LINQ.dbml designer et appelez-le comme vous faites vos autres objets. Le LINQ connaît même les colonnes de votre fonction stockée. Je l'appelle comme ceci ::

Dim db As New NobleLINQ
Dim LNameSearch As String = txt_searchLName.Text
Dim hlink As HyperLink

For Each ee In db.getMatches(LNameSearch)
   hlink = New HyperLink With {.Text = ee.Fullname & "<br />", .NavigateUrl = "?ID=" & ee.ID}
   pnl_results.Controls.Add(hlink)
Next

incroyablement simple et utilise vraiment la puissance de SQL et LINQ dans le application...et vous pouvez, bien sûr, générer une fonction à valeur de table que vous voulez pour les mêmes effets!

0
répondu beauXjames 2010-06-18 18:52:59

je crois que ce que vous voulez vraiment, c'est: imaginons un scénario vous avez deux bases de données et ils ont une table de produits en commun Et vous voulez sélectionner des produits du tableau "A" que id a en commun avec le" B "

l'utilisation de la méthode contains serait trop compliquée pour le faire ce que nous faisons est une intersection, et il y a une méthode appelée intersection pour cela

exemple de msdn: http://msdn.microsoft.com/en-us/vcsharp/aa336761.aspx#intersect1

int [] nombres = (0, 2, 4, 5, 6, 8, 9); int [] numbersB = (1, 3, 5, 7, 8); var = commonNumbers numbersA.Intersect (numbersB);

je pense que ce que vous avez besoin est facilement résolu avec l'intersection

0
répondu Lucas Cria 2010-08-04 03:22:02

vérifier cette méthode d'extension:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace ContainsAnyProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            const string iphoneAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like...";

            var majorAgents = new[] { "iPhone", "Android", "iPad" };
            var minorAgents = new[] { "Blackberry", "Windows Phone" };

            // true
            Console.WriteLine(iphoneAgent.ContainsAny(majorAgents));

            // false
            Console.WriteLine(iphoneAgent.ContainsAny(minorAgents));
            Console.ReadKey();
        }
    }

    public static class StringExtensions
    {
        /// <summary>
        /// Replicates Contains but for an array
        /// </summary>
        /// <param name="str">The string.</param>
        /// <param name="values">The values.</param>
        /// <returns></returns>
        public static bool ContainsAny(this string str, params string[] values)
        {
            if (!string.IsNullOrEmpty(str) && values.Length > 0)
                return values.Any(str.Contains);

            return false;
        }
    }
}
0
répondu ron.camaron 2012-08-10 13:55:19
from xx in table
where xx.uid.Split(',').Contains(string value )
select xx
0
répondu user1119399 2012-10-11 01:34:45

, Essayez:

var stringInput = "test";
var listOfNames = GetNames();
var result = from names in listOfNames where names.firstName.Trim().ToLower().Contains(stringInput.Trim().ToLower());
select names;
0
répondu Hedego 2015-08-08 16:00:05
string[] stringArray = {1,45,20,10};
from xx in table 
where stringArray.Contains(xx.uid.ToString()) 
select xx
-1
répondu knroc 2012-12-13 14:32:46
Dim stringArray() = {"Pink Floyd", "AC/DC"}
Dim inSQL = From alb In albums Where stringArray.Contains(alb.Field(Of String)("Artiste").ToString())
Select New With
  {
     .Album = alb.Field(Of String)("Album"),
     .Annee = StrReverse(alb.Field(Of Integer)("Annee").ToString()) 
  }
-2
répondu EVONZ 2016-10-16 18:54:17