具有延迟执行和 SQL 侧分组的 EF Core Group By
EF Core Group By with Deferred Execution and SQL side grouping
使用 EF Core 2.1,它支持按翻译分组,但在我投射键值后不支持。
我有一个查询需要允许一系列分组类型和一系列聚合类型。
分组依据:年,Year/Month,Year/Month/天等
聚合依据:平均值、总和、最小值、最大值等
我创建了两个 switch
语句,一个用于分组,一个用于聚合。我的问题是我无法推迟执行并在 SQL 内执行分组。如果不是,则生成的数据集非常大。
这是一种合理的方法还是我应该只使用原始查询?
这是根据需要延迟和分组的,但密钥类型是 year/month 所独有的,如果我想分组,我无法为第二个 switch
中的聚合提供通用解决方案通过一些不同的东西,例如 year/month/day.
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) });
一旦您将密钥转换为字符串,就会在客户端进行分组:
var query2 = series
.GroupBy(k => k.Created.Year.ToString());
var result2 = query2
.Select(i => new { i.Key, Value = i.Average(a => a.DataValue) });
这也会导致客户端发生分组:
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()
});
有什么办法可以完成我的查询吗?理想情况下,我需要一个通用的组键来对服务器端进行分组,或者需要一种基于查询中的函数传递聚合的方法。生成基于 string
的密钥似乎可以确保分组发生在客户端。
我能够在 EF Core 2.1(和 2.2)中获得 SQL 翻译的唯一方法是按复合 anonymous 类型分组,有条件地包括所需的数据部分:
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
});
奇怪的是,如果我为具有与匿名类型完全相同的属性的组键创建一个特殊的 class 并将 new { ... }
更改为 new MyKeyType { ... }
,EF Core 会切换到客户端评估.
不久,GroupBy
(不仅如此)SQL 翻译仍然不稳定。看起来我们必须等待 3.0 才能最终在该领域得到改进。
使用 EF Core 2.1,它支持按翻译分组,但在我投射键值后不支持。
我有一个查询需要允许一系列分组类型和一系列聚合类型。
分组依据:年,Year/Month,Year/Month/天等
聚合依据:平均值、总和、最小值、最大值等
我创建了两个 switch
语句,一个用于分组,一个用于聚合。我的问题是我无法推迟执行并在 SQL 内执行分组。如果不是,则生成的数据集非常大。
这是一种合理的方法还是我应该只使用原始查询?
这是根据需要延迟和分组的,但密钥类型是 year/month 所独有的,如果我想分组,我无法为第二个 switch
中的聚合提供通用解决方案通过一些不同的东西,例如 year/month/day.
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) });
一旦您将密钥转换为字符串,就会在客户端进行分组:
var query2 = series
.GroupBy(k => k.Created.Year.ToString());
var result2 = query2
.Select(i => new { i.Key, Value = i.Average(a => a.DataValue) });
这也会导致客户端发生分组:
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()
});
有什么办法可以完成我的查询吗?理想情况下,我需要一个通用的组键来对服务器端进行分组,或者需要一种基于查询中的函数传递聚合的方法。生成基于 string
的密钥似乎可以确保分组发生在客户端。
我能够在 EF Core 2.1(和 2.2)中获得 SQL 翻译的唯一方法是按复合 anonymous 类型分组,有条件地包括所需的数据部分:
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
});
奇怪的是,如果我为具有与匿名类型完全相同的属性的组键创建一个特殊的 class 并将 new { ... }
更改为 new MyKeyType { ... }
,EF Core 会切换到客户端评估.
不久,GroupBy
(不仅如此)SQL 翻译仍然不稳定。看起来我们必须等待 3.0 才能最终在该领域得到改进。