2010-09-15 9 views
5

Questa funzione viene utilizzata per restituire un elenco di contatti per un input di ricerca degli utenti. Il numero di termini di ricerca è sempre almeno uno, ma potrebbe essere molti.Qual è il modo corretto per aggiungere dinamicamente un numero indeterminato di clausole a una query Sql Linq 2?

public IList<Contact> GetContacts(string[] searchTerms) 
{ 
    using (dbDataContext db = new dbDataContext()) 
    { 
     var contacts = from _contacts in db.Contacts 
         orderby _contacts.LastName ascending, _contacts.FirstName ascending 
         select _contacts; 

     foreach (string term in searchTerms) 
     { 
      contacts = (IOrderedQueryable<Contact>)contacts.Where(x => SqlMethods.Like(x.FirstName, "%" + term + "%") 
                    || SqlMethods.Like(x.MiddleName, "%" + term + "%") 
                    || SqlMethods.Like(x.LastName, "%" + term + "%") 
                    || SqlMethods.Like(x.PreferredName, "%" + term + "%")); 
     } 

     return contacts.ToList<Contact>(); 
    } 
} 

Il problema è nel ciclo. Viene utilizzato solo l'ultimo termine di ricerca, anche se lo sql generato sembra corretto (poiché viene generato il numero corretto di clausole per il numero di termini).

Esempio: se si passano due termini ('andr', 'sm'), lo sql generato mostra due blocchi di clausole come richiesto, ma usa solo 'sm' come parametro in entrambi i blocchi.

Cosa sto sbagliando? Dovrei anche usare SqlMethods?

+1

Si dice che l'SQL generato sembra corretto, puoi pubblicarlo? Hai provato a eseguire manualmente l'SQL generato? –

+0

sì funziona se eseguo manualmente, è solo usando l'ultimo 'termine' nella matrice come parametro per tutti i parametri. Strano. – IckleMonkey

risposta

5

Forse il problema è catturare il termine variabile del ciclo. Prova questo:

foreach (string term in searchTerms) 
{ 
    string t = term; 
    contacts = ... // use t instead of term 
} 
+0

Il mio amico è un genio. Lavori!!! – IckleMonkey

+0

Sai perché questo sarebbe successo? – IckleMonkey

+0

perché si sta chiudendo una variabile di ciclo, quindi quando si arriva a eseguire il termine di query è sempre l'ultimo valore nell'array passato. vedi questa domanda: http://stackoverflow.com/questions/227820/why-is-it-bad-to-use-a-iteration-variable-in-a-lambda-expression –

Problemi correlati