2010-09-07 19 views
6

Mi sono strappato i capelli con questo. Ho una serie di termini di ricerca e sto cercando di eseguire una query LINQ su SQL per cercare valori di campo rispetto a ciascun elemento dell'array.LINQ to SQL query help (la stringa contiene qualsiasi stringa nell'array di stringhe)

ho ottenuto fino a questo punto ..

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; 

... ma poi ottenuto

sequenza locale non può essere utilizzato in LINQ alla implementazione di SQL di interrogazione operatori tranne il contains() operatore

... e ora sono bloccato.

Se qualcuno può aiutare sarei molto grato. Grazie in anticipo.

Rob

risposta

5

Non sono sicuro se questa è la soluzione più semplice, ma questo funzionerà:

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

Sarà necessario il PredicateBuilder per questo al lavoro.

+0

Wow - mi piacerebbe venire attraverso il termine 'costruttore predicato' durante la ricerca di una soluzione, ma nessuno del spiegato in termini così semplici! Grazie mille!! – LiverpoolsNumber9

-1

Un'opzione sarebbe quella di eseguire il filtro sul client anziché in SQL. È possibile forzare lo where da valutare sul client chiamando AsEnumerable(). Tuttavia, ciò significa che ogni riga della tabella viene caricata in memoria prima di essere testata per una corrispondenza, pertanto potrebbe risultare inaccettabilmente inefficiente se la ricerca corrisponde solo a un numero limitato di risultati da una tabella di grandi dimensioni.

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ì, ho pensato, e in realtà sono solo 1200 record, quindi non sarebbe male. Ma il mio OCD in fase di caricamento mi sta fermando ... :) – LiverpoolsNumber9

+0

Il problema può essere che funziona perfettamente su un piccolo database di test, ma una volta che il client ottiene dati più grandi, fallirà gloriosamente. Mi sono imbattuto in un caso in cui stavamo guardando attraverso una tabella di log con 4,8 milioni di righe e caricando tutto e quindi il filtraggio non era solo un'opzione. – MBentley