Comment utiliser LINQ Contains (chaîne ) au lieu de Contient (chaîne)

J’ai une grande question.

J’ai eu une requête linq pour le mettre simplement comme ceci:

from xx in table where xx.uid.ToSsortingng().Contains(ssortingng[]) select xx 

Les valeurs du tableau ssortingng[] seraient des nombres comme (1,45,20,10, etc …)

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

J’en ai besoin pour le faire à la place: .Contains(ssortingng[])

EDIT: Un utilisateur a suggéré d’écrire une classe d’extension pour ssortingng[] . Je voudrais apprendre comment, mais quelqu’un prêt à me diriger dans la bonne direction?

EDIT: Le uid serait aussi un numéro. C’est pourquoi il est converti en chaîne.

Aidez quelqu’un?

spoulson a presque raison, mais vous devez d’abord créer une List partir de la ssortingng[] . En fait, une List serait préférable si uid est également int . List supporte Contains() . Faire uid.ToSsortingng().Contains(ssortingng[]) impliquerait que le uid en tant que chaîne contient toutes les valeurs du tableau en tant que sous-chaîne ??? Même si vous avez écrit la méthode d’extension, vous vous en rendrez compte.

[MODIFIER]

À moins que vous ne l’ayez modifié et écrit pour une ssortingng[] comme le montre Mitch Wheat, vous ne pourrez alors que sauter l’étape de conversion.

[ENDEDIT]

Voici ce que vous voulez, si vous ne faites pas la méthode d’extension (à moins que vous ne disposiez déjà de la collection d’uids potentiels ints – alors utilisez simplement List() ). Cela utilise la syntaxe de la méthode chaînée, qui est plus propre à mon avis, et effectue la conversion en int pour garantir que la requête puisse être utilisée avec plusieurs fournisseurs.

 var uids = arrayofuids.Select(id => int.Parse(id)).ToList(); var selected = table.Where(t => uids.Contains(t.uid)); 

Si vous cherchez vraiment à répliquer Contient , mais pour un tableau, voici une méthode d’extension et un exemple de code à utiliser:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ContainsAnyThingy { class Program { static void Main(ssortingng[] args) { ssortingng 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 SsortingngExtensions { public static bool ContainsAny(this ssortingng str, params ssortingng[] values) { if (!ssortingng.IsNullOrEmpty(str) || values.Length > 0) { foreach (ssortingng value in values) { if(str.Contains(value)) return true; } } return false; } } } 

Essayez ce qui suit

 ssortingng input = "someSsortingng"; ssortingng[] toSearchFor = GetSearchSsortingngs(); var containsAll = toSearchFor.All(x => input.Contains(x)); 

LINQ dans .NET 4.0 a une autre option pour vous; la méthode .Any ();

 ssortingng[] values = new[] { "1", "2", "3" }; ssortingng data = "some ssortingng 1"; bool containsAny = values.Any(data.Contains); 

Ou si vous avez déjà les données dans une liste et préférez l’autre format Linq 🙂

 List uids = new List(){"1", "45", "20", "10"}; List table = GetDataFromSomewhere(); List newTable = table.Where(xx => uids.Contains(xx.uid)).ToList(); 

Que diriez-vous:

 from xx in table where ssortingngarray.Contains(xx.uid.ToSsortingng()) select xx 

Voici un exemple d’écriture d’une méthode d’extension (remarque: je ne l’utiliserais pas pour de très grands tableaux, une autre structure de données serait plus appropriée …):

 namespace SsortingngExtensionMethods { public static class SsortingngExtension { public static bool Contains(this ssortingng[] ssortingngarray, ssortingng pat) { bool result = false; foreach (ssortingng s in ssortingngarray) { if (s == pat) { result = true; break; } } return result; } } } 

C’est une réponse tardive, mais je crois que c’est toujours utile .
J’ai créé le package nuget NinjaNye.SearchExtension qui peut vous aider à résoudre ce problème:

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

Vous pouvez également rechercher plusieurs propriétés de chaîne

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

Ou effectuez une recherche de RankedSearch qui renvoie IQueryable> qui inclut simplement une propriété indiquant 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 existe un guide plus complet sur la page des projets GitHub: https://github.com/ninjanye/SearchExtensions

J’espère que cela aidera les futurs visiteurs

Je crois que vous pourriez aussi faire quelque chose comme ça.

 from xx in table where (from yy in ssortingng[] select yy).Contains(xx.uid.ToSsortingng()) select xx 

Méthode d’extension Linq. Travaillera avec n’importe quel object IEnumerable:

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

Usage:

 ssortingng[] Array1 = {"1", "2"}; ssortingng[] Array2 = {"2", "4"}; bool Array2ItemsInArray1 = List1.ContainsAny(List2); 

Alors, est-ce que je suppose que uid est un identifiant unique (Guid)? Est-ce juste un exemple de scénario possible ou essayez-vous vraiment de trouver un GUI correspondant à un tableau de chaînes?

Si cela est vrai, vous voudrez peut-être 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 dans lequel une correspondance entre un tableau de chaînes utilisant “contains” et le contenu d’un Guid serait une bonne idée. D’une part, Contains () ne garantit pas l’ordre des nombres dans le Guid afin que vous puissiez potentiellement correspondre à plusieurs éléments. Sans parler de comparer les guids de cette façon serait beaucoup plus lent que de le faire directement.

Vous devriez l’écrire dans l’autre sens, en vérifiant que votre liste d’ID utilisateur privilégié contient l’ID sur cette rangée de table:

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

LINQ se comporte très clairement ici et le convertit en une bonne instruction 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 basiquement le contenu du tableau ‘search’ dans la requête sql et effectue le filtrage avec le mot clé ‘IN’ en SQL.

J’ai réussi à trouver une solution, mais pas une très bonne, car il faut utiliser AsEnumerable () qui renverra tous les résultats de la firebase database. Heureusement, je n’ai que 1 000 enregistrements dans la table. .

 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, SsortingngComparison.InvariantCultureIgnoreCase) >= 0) select u; 

Mon post original suit:

Comment faites-vous l’inverse? Je veux faire quelque chose comme ce qui suit dans le framework d’entités.

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

Ce que je veux, c’est trouver tous les utilisateurs où leur FullName contient tous les éléments de `search ‘. J’ai essayé un certain nombre de façons différentes, qui n’ont pas fonctionné pour moi.

J’ai aussi essayé

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

Cette version ne trouve que ceux qui contiennent le dernier élément du tableau de recherche.

La meilleure solution que j’ai trouvée consistait à créer une fonction de valeur de table dans SQL qui produirait 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, il vous suffit de faire glisser la fonction dans votre concepteur LINQ.dbml et de l’appeler comme vous le faites pour vos autres objects. Le LINQ connaît même les colonnes de votre fonction stockée. Je l’appelle comme ça ::

 Dim db As New NobleLINQ Dim LNameSearch As Ssortingng = txt_searchLName.Text Dim hlink As HyperLink For Each ee In db.getMatches(LNameSearch) hlink = New HyperLink With {.Text = ee.Fullname & "
", .NavigateUrl = "?ID=" & ee.ID} pnl_results.Controls.Add(hlink) Next

Incroyablement simple et utilise vraiment la puissance de SQL et LINQ dans l’application … et vous pouvez, bien sûr, générer toutes les fonctions de table que vous voulez pour les mêmes effets!

Je pense que ce que vous voulez vraiment faire, c’est: imaginons un scénario avec deux bases de données et une table de produits en commun. Et vous voulez sélectionner des produits de la table “A” que vous avez en commun avec le “B”

utiliser la méthode contains serait trop compliqué pour faire ce que nous faisons est une intersection, et il existe une méthode appelée intersection pour cela

un 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 dont vous avez besoin est facilement résolu avec l’intersection

Vérifiez cette méthode d’extension:

 using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace ContainsAnyProgram { class Program { static void Main(ssortingng[] args) { const ssortingng 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 SsortingngExtensions { ///  /// Replicates Contains but for an array ///  /// The ssortingng. /// The values. ///  public static bool ContainsAny(this ssortingng str, params ssortingng[] values) { if (!ssortingng.IsNullOrEmpty(str) && values.Length > 0) return values.Any(str.Contains); return false; } } } 
 from xx in table where xx.uid.Split(',').Contains(ssortingng value ) select xx 

Essayer:

 var ssortingngInput = "test"; var listOfNames = GetNames(); var result = from names in listOfNames where names.firstName.Trim().ToLower().Contains(ssortingngInput.Trim().ToLower()); select names; 
 ssortingng[] ssortingngArray = {1,45,20,10}; from xx in table where ssortingngArray.Contains(xx.uid.ToSsortingng()) select xx 
 Dim ssortingngArray() = {"Pink Floyd", "AC/DC"} Dim inSQL = From alb In albums Where ssortingngArray.Contains(alb.Field(Of Ssortingng)("Artiste").ToSsortingng()) Select New With { .Album = alb.Field(Of Ssortingng)("Album"), .Annee = StrReverse(alb.Field(Of Integer)("Annee").ToSsortingng()) }