EF Core Group By与延迟执行和SQL侧分组

时间:2018-12-09 17:34:05

标签: c# entity-framework linq entity-framework-core ef-core-2.1

使用支持Core By转换的EF Core 2.1,但在我投影键值之后不支持。

我有一个查询,需要允许一定范围的分组类型和一定范围的聚合类型。

分组依据:年,年/月,年/月/日等

汇总依据:平均,总和,最小值,最大值等

我创建了两个from datetime import timedelta cond1 = df.DateTime-df.DateTime.shift(1) > pd.Timedelta(15, 'm') #OR #15_min = df.DateTime.diff() > pd.Timedelta(minutes=15) cond2 = df.location != df.location.shift(1) session_id = (cond1|cond2).cumsum() df['session_id'] = session_id.map(pd.Series(range(0,10000))) 语句,一个用于分组,一个用于聚合。我的问题是我无法推迟执行并在SQL中执行分组。如果不是,则结果数据集会很大。

这是一种合理的方法还是应该只使用原始查询?

这是根据需要进行延迟和分组的,但是键类型对于年份/月份是唯一的,并且如果我想按不同的分组方式,则无法为第二个switch中的聚合提供通用的解决方案作为年/月/日。

switch

将密钥转换为字符串后,将在客户端进行分组:

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() }); 的密钥似乎可以确保分组发生在客户端。

1 个答案:

答案 0 :(得分:3)

我能够在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
    });

很奇怪,如果我为组密钥创建一个特殊的类,使其具有与匿名类型完全相同的属性,并将new { ... }更改为new MyKeyType { ... },EF Core将切换到客户端评估。

很快,GroupBy(不仅是)SQL翻译仍然不稳定。看起来我们必须等待3.0才能在该领域获得最终的改进。