Utilizzo di EF Core 2.1 che supporta la traduzione di Group By ma non dopo la proiezione del valore della chiave.
Ho una query che deve consentire una gamma di tipi di raggruppamento e un intervallo di tipi aggregati.
Raggruppa per: anno, anno / mese, anno / mese / giorno ecc
Aggregato per: Avg, Sum, Min, Max ecc.
Ho creato due istruzioni switch
, una per il raggruppamento e una per l'aggregazione. Il mio problema è che non sono in grado di posticipare l'esecuzione ed eseguire il raggruppamento all'interno di SQL. In caso contrario, il set di dati risultante è piuttosto grande.
Qualunque cosa è un approccio ragionevole o dovrei semplicemente utilizzare una query non elaborata?
Questo viene differito e raggruppato come desiderato ma il tipo di chiave è unico per anno / mese e non sono in grado di fornire una soluzione generale per gli aggregati nel secondo switch
se volessi raggruppare per qualcosa di diverso come anno / mese / giorno.
var query1 = series
.GroupBy(k => new { k.Created.Year, k.Created.Month, });
var result1 = query1
.Select(i => new { i.Key, Value = i.Average(a => a.DataValue) });
Non appena si converte la chiave in una stringa, il raggruppamento si verifica sul lato client:
var query2 = series
.GroupBy(k => k.Created.Year.ToString());
var result2 = query2
.Select(i => new { i.Key, Value = i.Average(a => a.DataValue) });
Anche questo fa sì che il raggruppamento si verifichi lato client:
var query3 = series
.GroupBy(k => new { k.Created.Year, k.Created.Month, })
.Select(i => new
{
Key = $"{i.Key.Year}-{i.Key.Month}",
Values = i.ToList()
});
Qualche idea su come realizzare la mia domanda? Idealmente ho bisogno di una chiave di gruppo comune che raggruppa il lato server o un metodo per passare l'aggregato in base a una funzione nella query. La generazione di una chiave basata su string
sembra garantire che il raggruppamento si verifichi sul lato client.
L'unico modo per ottenere la traduzione SQL in EF Core 2.1 (e 2.2) era raggruppare per tipo anonimo composito condizionatamente includendo le parti di dati desiderate:
bool includeYear = ...;
bool includeMonth = ...;
bool includeDay = ...;
bool includeHour = ...;
var query1 = series
.GroupBy(e => new
{
Year = includeYear ? e.CreatedDate.Year : 0,
Month = includeMonth ? e.CreatedDate.Month : 0,
Day = includeDay ? e.CreatedDate.Day : 0,
Hour = includeHour ? e.CreatedDate.Hour : 0
});
Stranamente, se creo una classe speciale per la chiave di gruppo con le stesse proprietà del tipo anonimo e cambia il new { ... }
con il new MyKeyType { ... }
, EF Core passa alla valutazione del cliente.
In breve, GroupBy
(e non solo) la traduzione SQL è ancora instabile. Sembra che dovremo aspettare 3.0 per ottenere finalmente miglioramenti in quell'area.