2011-08-16 8 views
8

Witam próbuję użyć funkcji DefaultIfEmpty() na IQueryable i rzuca wyjątek "Nieobsługiwane przeciążenie używane dla operatora zapytania" DefaultIfEmpty "." to mój kod:DefaultIfEmpty() nie działa

Dinner defaultDinner = db.Dinners.Where(d => d.DinnerID == 5).Single(); 
Dinner blah; 
IQueryable<Dinner> bla = db.Dinners.Where(d => d.DinnerID == id) 
          .DefaultIfEmpty(defaultDinner); 
blah = bla.First(); 
return blah; 

znalazłem inny sposób to zrobić bez DefaultIfEmpty ale nadal chcę wiedzieć, jak rozwiązać ten problem ... tutaj jest pierwszą częścią z wyjątkiem:

Opis: Wystąpił nieobsługiwany wyjątek podczas wykonywania bieżącego żądania WWW. Sprawdź ślad stosu, aby uzyskać więcej informacji o błędzie i skąd pochodzi w kodzie.

Szczegóły wyjątku: System.NotSupportedException: nieobsługiwane przeciążenie używane dla operatora zapytania "DefaultIfEmpty".

Odpowiedz

14

Wydaje się dość oczywiste dla mnie jest:

nieobsługiwany przeciążenie wykorzystywane do operatora zapytania 'DefaultIfEmpty'

Brzmi jak dostawcy LINQ (które nie zostało określone) nie obsługuje przeciążenia DefaultIfEmpty, które wymaga usunięcia ult wartość.

Najprostszym rozwiązaniem jest prawdopodobnie używać:

var ret = db.Dinners.Where(d => d.DinnerID == id) 
        .FirstOrDefault(); 
return ret ?? db.Dinners.Where(d => d.DinnerID == 5).Single(); 

Należy zauważyć, że takie podejście pozwala uniknąć pobierania „domyślny” obiad, chyba że jest to wymagane, dlatego też bardziej wydajne.

(Jeśli nie powinien być tylko jeden wynik dla każdego ID, powinieneś użyć SingleOrDefault zamiast FirstOrDefault na drodze. Jest to bardziej logiczne, że sposób).

+0

Używam: system.data.linq.table –

+0

@ Ella: Więc LINQ to SQL następnie ... –

+0

Tak, linq do sql db –

2

Wypróbuj

Dinner dinner = db.Dinners.SingleOrDefault(d => d.DinnerID == id); 
+0

Którą "Domyślną" metodą jest ta? Nie jestem zaznajomiony z tym w Queryable ... –

+0

Problem polega na tym, że '' Default'' zwrócony przez '' SingleOrDefault'' jest wartością domyślną * dla tego typu *. W tym przypadku, ponieważ '' Dinner'' jest klasą, będzie to '' null''. – BishopRook

+0

@Jon Skeet: usunąłem to już, wymieszałem to z czymś, czego nie pamiętam dokładnie .. ale gdzieś widziałem taką składnię – sll

1

Sposób DefaultIfEmpty rzuca NotSupportedException gdy wezwał IQueryable<T>. Możesz wykonać wyraźną obsadę na IEnumerable<T>, dzwoniąc pod numer db.Dinners.Where(d => d.DinnerId == id).ToEnumerable().First().

Najprawdopodobniej użytkownik nie powinien używać tej metody. Lepiej po prostu sprawdzić, czy wywołanie zwróciło jakiekolwiek wartości, i pobrać domyślne, jeśli nie.

Edytuj: Oop. Nie, Jon Skeet ma rację. Metoda rozszerzenia DefaultIfEmpty opiera się na implementacji od dostawcy zapytań, więc zdecydowanie zależy od tego, jakiego dostawcy zapytań jest używany.

+0

Z pewnością, czy zgłasza wyjątek, zależy od * implementacji * IQueryable . Nic nie stoi na przeszkodzie, aby obsłużyć tego operatora bez żadnych problemów. –

+0

'' DefaultIfEmpty'' jest metodą rozszerzenia w '' System.Linq'', nie jest członkiem klasy implementującej '' IQueryable '' * lub * '' IEnumerable ''. Więc nie, nie widzę, jak ważna byłaby implementacja? – BishopRook

+0

Jest to metoda rozszerzenia w Queryable, yes - która wywołuje "IQueryable " w pierwszym parametrze. Wdrożenie * bardzo * ma znaczenie. Na przykład, spróbuj 'string y = nowy ciąg [0] .AsQueryable(). DefaultIfEmpty (" foo "). First();' - który powiedzie się bez problemów, pomimo wciąż wywoływania 'Queryable.DefaultIfEmpty'. –