Mam tabelę Pracownicy:
EmployeeID | EmployeeName
---------------------------
1 | Jack
2 | Jill
3 | Roger
I tabela Występowania:
OccurrenceID | EmployeeID | Points
--------------------------------------
1 | 1 | 5
2 | 2 | 3
3 | 1 | 1
Mam działające zapytanie LINQ, które grupuje i sumuje dwie tabele razem:
groupedOccurrences = (from o in db.Occurrences.Include(o => o.Employee)
where o.OccurrenceDate >= beginDate
&& o.OccurrenceDate <= endDate
group o by o.Employee.EmployeeName into g
select new OccurrenceByQuarter
{
Name = g.Key,
Total = g.Sum(o => o.Points)
});
Który wytwarza to wyjście:
Jack 6
Jill 3
Ale chcę, aby pracownik Roger pojawił się na wyjściu z 0 punktami. Próbowałem dodać złączenie do zapytania LINQ w następujący sposób:
groupedOccurrences = (from e in db.Employees
from o in db.Occurrences
join o in db.Occurrences on e.EmployeeID equals o.EmployeeID into j1
from j2 in j1.DefaultIfEmpty()
group j2 by e.EmployeeName into g
select new OccurrenceByQuarter
{
Name = g.Key,
Total = g.Sum(o => o.Points)
});
Skończyło się jednak na tym, że liczba punktów była znacznie zawyżona (jak w 24-krotności tego, czym powinny być).
Próbowałem również, aby suma zwróciła 0, jeśli jest pusta, zmieniając deklarację sumy na public int? Total { get; set; }
w mojej klasie OccurrencesByQuarter, ale kiedy próbuję zmienić zapytanie LINQ, aby uwzględnić Total = g.Sum(o => o.Points) ?? 0
Pojawia się komunikat o błędzie „operator ?? nie może być stosowany do operandów typu int i int”.
Każda pomoc byłaby bardzo cenna.
Odpowiedzi:
6 dla odpowiedzi № 1Użyj dołączenia do grupy:
groupedOccurrences = (from e in db.Employees
join o in db.Occurrences.Where(x =>
x.OccurrenceDate >= beginDate &&
x.OccurrenceDate <= endDate)
on e.EmployeeID equals o.EmployeeID into g
select new OccurrenceByQuarter
{
Name = e.EmployeeName,
Total = g.Sum(x => (int?)x.Points) ?? 0
});
Wynik będzie:
Jack 6
Jill 3
Roger 0
Aby wrócić 0
w przypadku pustych grup rzutuj podsumowaną właściwość na wartość zerową, a następnie zastosuj operator zerowania, aby zwrócić wartość domyślną: g.Sum(x => (int?)x.Points) ?? 0