2010-09-28 12 views
7

Biorąc to zapytanie:problem z LINQ podmiotom zapytania używając Sum na obiekt podrzędny nieruchomość

from s in services 
select new 
{ 
    s.Id, 
    s.DateTime, 
    Class = s.Class.Name, 
    s.Location, 
    s.Price, 
    HeadCount = s.Reservations.Sum(r => r.PartySize), // problem here. r.PartySize is int 
    s.MaxSeats 
} 

Jeśli usługa nie ma żadnych zastrzeżeń, to jest wyjątek:

System.InvalidOperationException : Odrzucenie do typu wartości "Int32" nie powiodło się, ponieważ zmaterializowana wartość jest pusta. Typowy parametr typu wynikowego lub zapytanie muszą używać typu zerowego.

Rozumiem, ale jak mam sobie z tym poradzić? Moją intencją jest, jeśli nie ma żadnych zastrzeżeń, a następnie Zatrudnienie być przypisane 0.

Odpowiedz

7

Należy sprawdzić na nim:

HeadCount = s.Reservations != null ? s.Reservations.Sum(r => r.PartySize) : 0, 
+0

Zamieściłem to pytanie przed próbą, że tylko dlatego, że zakłada się, że LINQ do udziałów w jednostkach nie będzie w stanie przekształcić go do SQL lub coś w tym stylu. Wciąż przyzwyczajam się do L2E, który wydaje się dużo bardziej wybredny niż LINQ do SQL, o to, co można faktycznie zrobić w instrukcji LINQ. W każdym razie to działa i nigdy nie należy zakładać. Dzięki. –

+0

@Ronnie cieszę się, że zadziałało. Są zdecydowanie inne i wyobrażam sobie, że L2E stanie się bardziej elastyczny w przyszłości. –

+0

To zadziała, ale jest łatwiejsze rozwiązanie. –

1

Prosty operator trójargumentowy powinno rozwiązać problem ładnie ...

coś to:

HeadCount = (s.Reservations != null && s.Reservations.Any()) ? s.Reservations.Sum(r => r.PartySize) : 0; 

to uchwyt dla obu sytuacjach nieważną i pustych

+0

Nie sądzę, że kod będzie się nawet kompilował (brakujące '()'). Z pewnością nie da wydajnego SQL (nigdy nie używaj '.Count() == 0', gdy masz na myśli' Any() '), ale nawet to jest zarówno nieskuteczne i trudne do odczytania w porównaniu z. Wbudowana null L2E się zlewa). –

+0

Masz rację, nie skompiluje się, ponieważ Count brakuje "()". Napisał to w locie -_-. Każde byłoby również bardziej wydajne. Dziękuję za poprawienie mnie! –

11

Istnieje jeszcze prostsze rozwiązanie:

from s in services 
select new 
{ 
    s.Id, 
    s.DateTime, 
    Class = s.Class.Name, 
    s.Location, 
    s.Price, 
    HeadCount = (int?)s.Reservations.Sum(r => r.PartySize), 
    s.MaxSeats 
} 

Uwaga na obsadę. Może to również tworzyć prostsze SQL niż sugestia @ Ahmada.

Zasadniczo pomagasz tylko wyciągać wnioski.

+0

Zgodnie z OP 'Reservations' może być' null', więc próba wywołania 'Suma (...)' na wartości zerowej nie jest możliwa. Przesyłanie do 'int?' Nie pomija wyjątku zerowego, który wystąpiłby w środowisku wykonawczym. Być może myślisz o rzucaniu wartości zerowej bezpośrednio, jak '(int?) R.PartySize'? –

+2

@Ahmad, to nie jest poprawne dla L2E, chociaż jest poprawne dla L2O. Mają różne zasady. Nie, nie myślę o rzuceniu wartości. Wypróbuj sugerowany kod; to działa. –

+1

+1 Przeoczyłem tłumaczenie, które ma miejsce dla tego dostawcy LINQ. –

2

To powinno rozwiązać problem: Spróbuj kosztować int do int?

from s in services 
select new 
{ 
    s.Id, 
    s.DateTime, 
    Class = s.Class.Name, 
    s.Location, 
    s.Price, 
    HeadCount = s.Reservations.Sum(r => (int?) r.PartySize), 
    s.MaxSeats 
}; 
HeadCount = HeadCount ?? 0;