Ho passato gli ultimi 6 mesi a combattere questa limitazione con EF 3.5 e mentre non sono la persona più intelligente del mondo, sono abbastanza sicuro di avere qualcosa di utile da offrire su questo argomento.
L'SQL generato dalla crescita di un albero alto 50 miglia con espressioni "OR style" si tradurrà in un piano di esecuzione delle query scadente. Ho a che fare con qualche milione di file e l'impatto è notevole.
C'è un piccolo hack che ho trovato a fare uno SQL 'in' che aiuta se sono solo alla ricerca di un gruppo di entità da ID:
private IEnumerable<Entity1> getByIds(IEnumerable<int> ids)
{
string idList = string.Join(",", ids.ToList().ConvertAll<string>(id => id.ToString()).ToArray());
return dbContext.Entity1.Where("it.pkIDColumn IN {" + idList + "}");
}
dove pkIDColumn è il tuo principale nome chiave colonna ID il tuo tavolo Entity1.
MA CONTINUI A LEGGERE!
Questo va bene, ma richiede che io abbia già gli id di ciò che ho bisogno di trovare. A volte voglio solo che le mie espressioni raggiungano altre relazioni e quello che ho sono i criteri per le relazioni connesse.
Se avessi più tempo proverei a rappresentarlo visivamente, ma non lo studio solo per un momento: consideri uno schema con tabelle Persona, GovernmentId e GovernmentIdType. Andrew Tappert (Persona) ha due carte d'identità (GovernmentId), una da Oregon (GovernmentIdType) e una da Washington (GovernmentIdType).
Ora generare un edmx da esso.
Ora immaginate che si desidera trovare tutte le persone che hanno un certo valore ID, dicono 1234567.
questo può essere realizzato con un unico database colpito con questo:
dbContext context = new dbContext();
string idValue = "1234567";
Expression<Func<Person,bool>> expr =
person => person.GovernmentID.Any(gid => gid.gi_value.Contains(idValue));
IEnumerable<Person> people = context.Person.AsQueryable().Where(expr);
vede il subquery Qui? Lo sql generato userà "join" invece di sottoquery, ma l'effetto è lo stesso. In questi giorni SQL server ottimizza le sottoquote in join sotto le copertine comunque, ma comunque ...
La chiave di questo funzionamento è il. Qualsiasi all'interno dell'espressione.
Grazie Daniel. La stessa sintassi funziona bene con Linq semplice. Quindi, sembra che il problema sia con EF in .Net 3.5 SP1 giusto? Il Contains senza parentesi è equivalente a: dove upperSearchList.All (x => (person.FirstName + person.LastName) .Contains (x)). ToList(); –
Se provo dove upperSearchList.All (arg => arg == arg) genera lo stesso errore. Quindi il problema è con il metodo All ... –
LINQ to Entities è una tecnologia meravigliosa, ma il motore di traduzione SQL è limitato. Non riesco a mettere le mani sulla documentazione ufficiale, ma secondo la mia esperienza, se la query include più di semplici funzioni matematiche e di stringa/data, non funzionerà. Hai avuto la possibilità di controllare che post ho collegato? Descrive un processo di conversione di una query di tipo "WHERE..IN" in una forma che LINQ to Entities può quindi tradurre in SQL. –