LINQ Group By wewnątrz Group By

0

Stworzyłem takiego potworka do zrobienia statystyk ile pozycji o danym kodzie produktu oraz o jakiej wartości zostało zafakturowanych w poszczególnych miesiącach:

            var groupAnalyticData = await _context.InvoiceItems
            .Where(g => !groupId.HasValue || g.Invoice.Customer.GroupId == groupId)
            .Where(s => s.Invoice.InvoiceDate >= startDate && s.Invoice.InvoiceDate <= endDate)
            .Where(s => s.Invoice.IsClosed == true && s.Invoice.IsExported == true)
            .Include(s => s.Invoice)
            .ThenInclude(d => d.Customer)
            .ThenInclude(f => f.Group)
            .GroupBy(g => g.Invoice.Customer.Group.Name, g => new { g.RemoteSystemServiceCode, g.Invoice.InvoiceDate.Value.Year, g.Invoice.InvoiceDate.Value.Month, g.NetValueAdded }, (groupName, data) => new GroupAnalyticData()
            {
                GroupName = groupName, 

                InvoiceMonths = Enumerable
                                   .Range(0, numberOfMonthsBetweenStartDateAndEndDate)
                                   .Select(i => endDate.AddMonths(-i).ToString("MMM yyyy"))
                                   .ToArray(),

                serviceItemGroupAnalyticData = data.GroupBy(f => f.RemoteSystemServiceCode, f => new { f.Year, f.Month, f.NetValueAdded }, (remoteSystemServiceCode, data) => new ServiceItemGroupAnalyticData()
                {
                    ServiceGroupName = remoteSystemServiceCode,
                    InvoiceItemsCounts = data.GroupBy(c => new { c.Year, c.Month }).Count(),
                    InvoiceItemsNetValueSums = data.GroupBy(g => new { g.Year, g.Month }).Sum(d => (double))
                })
            }).ToListAsync();
  1. Po dodaniu wewnętrznego GroupBy pojawia się błąd jak poniżej. Rozumiem, że Linq nie jest w stanie przetłumaczyć czegoś takiego i trzeba to wyliczyć po stronie klienta, ale nie wiem gdzie w tym kodzie trzeba wstawić ToList, żeby włączyć client-side evaluation

System.InvalidOperationException: The LINQ expression 'GroupByShaperExpression:
KeySelector: g.Name,
ElementSelector:new {
RemoteSystemServiceCode = ProjectionBindingExpression: RemoteSystemServiceCode,
Year = (int)ProjectionBindingExpression: Year,
Month = (int)ProjectionBindingExpression: Month,
NetValueAdded = (decimal)ProjectionBindingExpression: NetValueAdded
}
.GroupBy(
keySelector: f => f.RemoteSystemServiceCode,
elementSelector: f => new {
Year = f.Year,
Month = f.Month,
NetValueAdded = f.NetValueAdded
},
resultSelector: (remoteSystemServiceCode, data) => new ServiceItemGroupAnalyticData{
ServiceGroupName = remoteSystemServiceCode,
InvoiceItemsCounts = null,
InvoiceItemsNetValueSums = null
}
)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

  1. W jaki sposób wyliczyć skonstruować zapytania dla poniższych właściwości, żeby wyliczały liczbę oraz sumę wartości netto pozycji w poszczególnych miesiącach zwracając tablicę korespondującą z tablicą miesięcy InvoiceMonths.
                InvoiceItemsCounts = data.GroupBy(c => new { c.Year, c.Month }).Count(),
                InvoiceItemsNetValueSums = data.GroupBy(g => new { g.Year, g.Month }).Sum(d => (double))
1

Po dodaniu wewnętrznego GroupBy pojawia się błąd jak poniżej.

którego wewnętrznego?

tego

data.GroupBy(f => f.RemoteSystemServiceCode

czy

data.GroupBy(c => new { c.Year, c.Month })

A ta końcówka tego całego generowania, czyli ten duży GroupBy, to dużo tam dostaje danych?

Może wystarczyłoby po samych ThenInclude zrobić ToListAsync() i GroupBy niech leci na kliencie

1 użytkowników online, w tym zalogowanych: 0, gości: 1