2009-07-05 8 views
33

Quindi, sto cercando di restituire un insieme di persone il cui ID è contenuto all'interno di una collezione creata a livello locale di ID (IQueryable)lavoro intorno LinqToSQls "query con collezioni locali non sono supportati" eccezione

Quando ho specificato " raccolta localmente creata ", intendo che la raccolta Ids non proviene da una query LinqToSql ed è stata creata in modo programmatico (in base all'input dell'utente). La mia domanda è simile al seguente:

var qry = from p in DBContext.People 
        where Ids.Contains(p.ID) 
        select p.ID; 

Questo fa sì che la seguente eccezione ...

"non sono supportate le query con collezioni locali"

Come posso trovare tutte le persone con un ID che è contenuto nella mia raccolta Ids creata localmente?

È possibile utilizzare LinqToSql?

risposta

34

Se Id è un elenco, array o simile, L2S si tradurrà in un contenuto.

Se Id è un IQueryable, è sufficiente trasformarlo in un elenco prima di utilizzarlo nella query. Ad es .:

List<int> listOfIDs = IDs.ToList(); 
var query = 
from st in dc.SomeTable 
where listOfIDs.Contains(st.ID) 
select ..... 
+2

Penso che la soluzione al tuo problema sia più sfumata di questa risposta. Sto usando con successo la stessa costruzione (un metodo Contains su un IQueryable in una clausola WHERE), e LINQ to SQL lo traduce in una clausola WHERE EXISTS nella query SQL. Sembra funzionare in alcune situazioni e non in altre, quindi dovresti postare come ottieni IQueryable Ids, in quanto ciò potrebbe far luce sul problema. –

+1

@jmbledsoe se la mia risposta non era abbastanza chiara: L2S si aspetta un IEnumerable locale (non IQueryable differito) passato a Enumerable.Contains. Se si passa una query locale, che non può essere convertita in una query SQL. Se si passa una lista/array/etc allora può essere tradotto in una clausola SQL "dove ... in (x, y, ..., n)". – KristoferA

+2

Penso di vedere quello che stai dicendo: - Passare una lista/matrice/ecc. è OK b/c genererà una clausola WHERE ... IN. - Il passing differito IQueryable è OK b/c si integrerà con la query differita corrente. - Il passaggio di un oggetto IEnumerable locale NON è OK, ma puoi semplicemente .ToList() e andrà bene. –

26

Anche io stavo lottando con questo problema. Ha risolto il problema con l'utilizzo di qualsiasi() invece

people.Where(x => ids.Any(id => id == x.ID)) 
+0

@maxlego E l'SQL generato è in discesa. Grazie –

0

mi dispiace ma le risposte qui non ha funzionato per me come io sto facendo i tipi dinamici più avanti.

Quello che ho fatto è stato utilizzare "UNION" in un ciclo che funziona alla grande. Ecco come:

var firstID = cityList.First().id; 
var cities = dc.zs_Cities.Where(c => c.id == firstID); 
foreach(var c in cityList) 
{ 
    var tempCity = c; 
    cities = cities.Union(dc.zs_Cities.Where(cty => cty.id == tempCity.id)); 
} 
Problemi correlati