¿Cómo uso LINQ contiene (cadena ) en lugar de contiene (cadena)

Tengo una gran pregunta.

Tengo una consulta de linq para decir que simplemente se ve así:

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

Los valores de la matriz de string[] serían números como (1,45,20,10, etc …)

el valor predeterminado para .Contains es .Contains(string) .

Necesito que haga esto en su lugar: .Contains(string[])

EDITAR: Un usuario sugirió escribir una clase de extensión para la string[] . Me gustaría aprender cómo, pero ¿alguien dispuesto a orientarme en la dirección correcta?

EDITAR: El uid también sería un número. Es por eso que se convierte en una cadena.

Ayuda a alguien?

spoulson lo tiene casi correcto, pero primero debe crear una List desde la string[] . En realidad, una List sería mejor si uid también es int . List admite Contains() . Hacer uid.ToString().Contains(string[]) implicaría que el uid como una cadena contiene todos los valores de la matriz como una subcadena ??? Incluso si escribiste el método de extensión, el sentido sería incorrecto.

[EDITAR]

A menos que lo hayas cambiado y lo hayas escrito para la string[] como demuestra Mitch Wheat, entonces solo podrás saltearte el paso de conversión.

[ENDEDIT]

Esto es lo que desea, si no hace el método de extensión (a menos que ya tenga la colección de fluidos potenciales como elementos), simplemente use List() lugar). Esto utiliza la syntax del método encadenado, que creo que es más limpio, y realiza la conversión a int para garantizar que la consulta se pueda usar con más proveedores.

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

Si realmente desea replicar Contiene , pero para una matriz, aquí hay un método de extensión y un código de muestra para su uso:

 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; } } } 

Prueba lo siguiente.

 string input = "someString"; string[] toSearchFor = GetSearchStrings(); var containsAll = toSearchFor.All(x => input.Contains(x)); 

LINQ en .NET 4.0 tiene otra opción para ti; el método .Any ();

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

O si ya tiene los datos en una lista y prefiere el otro formato Linq 🙂

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

Qué tal si:

 from xx in table where stringarray.Contains(xx.uid.ToString()) select xx 

Este es un ejemplo de una forma de escribir un método de extensión (nota: no usaría esto para matrices muy grandes, otra estructura de datos sería más apropiada …):

 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; } } } 

Esta es una respuesta tardía, pero creo que todavía es útil .
Creé el paquete nuget NinjaNye.SearchExtension que puede ayudar a resolver este mismo problema .:

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

También puede buscar múltiples propiedades de cadenas

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

O realice un RankedSearch que devuelve IQueryable> que simplemente incluye una propiedad que muestra cuántas veces aparecieron los términos de búsqueda:

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

Hay una guía más extensa en la página de proyectos GitHub: https://github.com/ninjanye/SearchExtensions

Espero que esto ayude a los futuros visitantes

Creo que también podrías hacer algo como esto.

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

Método de extensión Linq. Funcionará con cualquier objeto IEnumerable:

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

Uso:

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

Entonces, ¿estoy asumiendo correctamente que uid es un identificador único (Guid)? ¿Es solo un ejemplo de un posible escenario o realmente estás tratando de encontrar un guid que coincida con una serie de cadenas?

Si esto es cierto, es posible que desee replantearse todo este enfoque, esto parece una muy mala idea. Probablemente deberías tratar de hacer coincidir un Guid con un Guid

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

Honestamente, no puedo imaginar un escenario en el que coincida con una matriz de cadenas que utilice “contiene” al contenido de un Guid sería una buena idea. Por un lado, Contains () no garantizará el orden de los números en el Guid, por lo que podría combinar varios elementos. Sin mencionar que comparar guías de esta manera sería mucho más lento que solo hacerlo directamente.

Debería escribirlo al revés, verificando que su lista de identificación de usuario privilegiada contenga el ID en esa fila de la tabla:

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

LINQ se comporta bastante shiny aquí y lo convierte en una buena statement 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' 

que básicamente incorpora el contenido de la matriz ‘búsqueda’ en la consulta sql, y lo filtra con la palabra clave ‘IN’ en SQL.

Me las arreglé para encontrar una solución, pero no una gran, ya que requiere el uso de AsEnumerable () que va a devolver todos los resultados de la base de datos, afortunadamente solo tengo 1k registros en la tabla, por lo que no es realmente notable, pero aquí va .

 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; 

Mi publicación original sigue:

¿Cómo haces el reverso? Quiero hacer algo como lo siguiente en el marco de la entidad.

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

Lo que quiero es encontrar todos los usuarios donde su nombre completo contenga todos los elementos en `búsqueda ‘. Lo intenté de diferentes maneras, todas las cuales no me han funcionado.

También intenté

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

Esta versión solo encuentra aquellas que contienen el último elemento en la matriz de búsqueda.

La mejor solución que encontré fue seguir adelante y crear una función con valores de tabla en SQL que produzca los resultados, tales como:

 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') 

Luego, simplemente arrastre la función a su diseñador LINQ.dbml y llámela como lo hace con sus otros objetos. El LINQ incluso conoce las columnas de su función almacenada. Lo digo así:

 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 & "
", .NavigateUrl = "?ID=" & ee.ID} pnl_results.Controls.Add(hlink) Next

Increíblemente simple y realmente aprovecha el poder de SQL y LINQ en la aplicación … ¡y puedes, por supuesto, generar cualquier función de tabla que quieras para los mismos efectos!

Creo que lo que realmente quieres hacer es: imaginemos que tienes dos bases de datos y tienen una tabla de productos en común Y quieres seleccionar productos de la tabla “A” que el ID tiene en común con la “B”

usar el método contiene sería demasiado complicado para hacer esto, lo que estamos haciendo es una intersección, y hay un método llamado intersección para eso

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

int [] números = (0, 2, 4, 5, 6, 8, 9); int [] númerosB = (1, 3, 5, 7, 8); var = números de Números comunesA.Intersect (númerosB);

Creo que lo que necesitas se resuelve fácilmente con la intersección

Verifique este método de extensión:

 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 { ///  /// Replicates Contains but for an array ///  /// The string. /// The values. ///  public static bool ContainsAny(this string str, params string[] values) { if (!string.IsNullOrEmpty(str) && values.Length > 0) return values.Any(str.Contains); return false; } } } 
 from xx in table where xx.uid.Split(',').Contains(string value ) select xx 

Tratar:

 var stringInput = "test"; var listOfNames = GetNames(); var result = from names in listOfNames where names.firstName.Trim().ToLower().Contains(stringInput.Trim().ToLower()); select names; 
 string[] stringArray = {1,45,20,10}; from xx in table where stringArray.Contains(xx.uid.ToString()) select xx 
 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()) }