2009-07-05 12 views
33

Tak, staram się zwracać kolekcję ludzi, których identyfikator jest zawarty w utworzonym lokalnie zbiór identyfikatorów (IQueryable)Praca wokół LinqToSQls „kwerend z lokalnej kolekcji nie są obsługiwane” wyjątek

Kiedy określenie " kolekcja utworzona lokalnie ", mam na myśli to, że kolekcja Ids nie pochodzi z zapytania LinqToSql i została utworzona programowo (na podstawie danych wprowadzonych przez użytkownika). Moja kwerenda wygląda następująco:

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

Powoduje następujący wyjątek ...

„zapytań lokalnych zbiorów nie są obsługiwane”

Jak mogę znaleźć wszystkie osoby z identyfikatorem, który jest zawarta w mojej kolekcji kreacji utworzonej lokalnie?

Czy to możliwe przy użyciu LinqToSql?

Odpowiedz

34

Jeśli Ids jest listą, tablicą lub podobnie, L2S przetłumaczy się na a zawiera.

Jeśli Ids jest produktem IQueryable, wystarczy go zamienić na listę przed użyciem w zapytaniu. Np .:

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

Myślę, że rozwiązanie twojego problemu jest bardziej dopracowane niż ta odpowiedź. Używam tej samej konstrukcji (metoda Contains na IQueryable w klauzuli WHERE), a LINQ do SQL przekształca ją w klauzulę WHERE EXISTS w zapytaniu SQL. Wygląda na to, że działa w niektórych sytuacjach, a nie w innych, więc powinieneś opublikować, jak zdobywasz Idquery IQueryable, ponieważ może to rzucić trochę światła na ten problem. –

+1

@ jmbledsoe, jeśli moja odpowiedź nie była wystarczająco jasna: L2S oczekuje, że lokalny IEnumerable (nie odroczony IQueryable) zostanie przekazany do Enumerable.Contains. Jeśli przekażesz to zapytanie lokalne, którego nie można przetłumaczyć na zapytanie SQL. Jeśli przekażesz mu listę/tablicę/etc, to można ją przetłumaczyć na klauzulę SQL "where ... in (x, y, ..., n)". – KristoferA

+2

Myślę, że widzę, co mówisz: - Przekazywanie listy/tablicy/itd. jest OK b/c wygeneruje klauzulę WHERE ... IN. - Przekazanie odroczonej wersji IQueryable jest OK b/c zostanie zintegrowane z bieżącym odroczonym zapytaniem. - Przekazywanie lokalnego IEnumerable NIE jest OK, ale możesz po prostu .ToList() to i będzie dobrze. –

26

również borykałem się z tym problemem. Rozwiązać mój problem z użyciem dowolnych() zamiast

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

@maxlego I wygenerowany SQL jest zejściem. Dzięki –

0

Przepraszam ale odpowiedzi tutaj nie działa na mnie jak robię dynamicznych rodzajów dalej wzdłuż.

To, co zrobiłem, to użyć "UNION" w pętli, która działa świetnie. Oto, jak:

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