2010-09-07 14 views
6

He estado rasgándome los pelos con esta. Tengo una serie de términos de búsqueda y estoy tratando de hacer una consulta de LINQ a SQL para buscar valores de campo en cada elemento de la matriz.Ayuda de consulta de LINQ to SQL (la cadena contiene cualquier cadena en una matriz de cadena)

Tengo este momento ..

var searchResults = 
    from x in SDC.Staff_Persons 
    where staffTermArray.Any(pinq => x.Forename.Contains(pinq)) 
     || staffTermArray.Any(pinq => x.Surname.Contains(pinq)) 
     || staffTermArray.Any(pinq => x.Known_as.Contains(pinq)) 
    orderby x.Surname 
    select x; 

... pero entonces tiene

secuencia local no se puede utilizar en LINQ a la implementación de SQL de consulta operadores excepto la contains() operador

... y ahora estoy atascado.

Si alguien puede ayudar, estaría muy agradecido. Gracias de antemano.

Rob

Respuesta

5

No estoy seguro si esto es la solución más fácil, pero esto va a funcionar:

var filter = CreateFilter(staffTermArray); 

var searchResults = 
    from person in SDC.Staff_Persons.Where(filter) 
    orderby person.Surname 
    select person; 



private static Expression<Func<Staff_Person, bool>> CreateFilter(
    string[] staffTermArray) 
{ 
    var predicate = PredicateBuilder.False<Staff_Person>(); 

    foreach (var staffTerm in staffTermArray) 
    { 
     // We need to make a local copy because of C# weirdness. 
     var ping = staffTerm; 

     predicate = predicate.Or(p => p.Forename.Contains(ping)); 
     predicate = predicate.Or(p => p.Surname.Contains(ping)); 
     predicate = predicate.Or(p => p.Known_as.Contains(ping)); 
    } 

    return predicate; 
} 

Necesitará el PredicateBuilder para que esto funcione.

+0

Wow - Me gustaría encontrar el término 'predicate builder' mientras buscaba la solución, pero nadie lo explicó en términos tan simples. ¡¡Muchas gracias!! – LiverpoolsNumber9

-1

Una opción sería filtrar en el cliente y no en SQL. Puede forzar que el where se evalúe en el cliente llamando al AsEnumerable(). Sin embargo, esto significa que cada fila de la tabla se carga en la memoria antes de probarse para una coincidencia, por lo que puede ser inaceptablemente ineficiente si su búsqueda coincide solo con una pequeña cantidad de resultados de una tabla grande.

var allPersons = 
    from x in SDC.Staff_Persons 
    orderby x.Surname 
    select x; 

var searchResults = 
    from x in allPersons.AsEnumerable() 
    where staffTermArray.Any(pinq => x.Forename.Contains(pinq)) 
     || staffTermArray.Any(pinq => x.Surname.Contains(pinq)) 
     || staffTermArray.Any(pinq => x.Known_as.Contains(pinq)) 
    select x; 
+0

Sí, tuve ese pensamiento, y en realidad son solo 1200 registros, así que no sería tan malo. Pero mi TOC de tiempo de carga me está deteniendo ... :) – LiverpoolsNumber9

+0

El problema puede ser que esto funciona muy bien en una pequeña base de datos de prueba, pero una vez que el cliente obtiene datos más grandes, fallará gloriosamente. Me encontré con un caso en el que estábamos mirando a través de una tabla de registro con 4,8 millones de líneas y cargando todo y luego el filtrado no era una opción. – MBentley

Cuestiones relacionadas