【问题标题】:Average of the difference of two DateTime objects with GroupBy in LINQ query在 LINQ 查询中使用 GroupBy 的两个 DateTime 对象的差异的平均值
【发布时间】:2021-02-17 12:06:14
【问题描述】:

我正在开发一个 ASP.NET Core 3.1 项目。我想根据 CreatedTimeModifiedTime 之间差异的平均值对 Tickets 中的 Services 进行分组门票。

基本上,我想知道关闭每种服务类型的票的平均分钟数。

类似这样的:

==========================
 Name        |  Avg. Mins
==========================

 Service 1   |   10 Mins
 Service 2   |   12 Mins
 Service 3   |   20 Mins

==========================

这是我尝试过的:

var d = _dbcontext.Tickets.Include(m => m.Services)
           .Where(m => m.ServiceId != null)
           .GroupBy(t => new { Name = t.Services.Name })
           .Select(m => new { x = m.Key.Name , y = m.Average(p => (p.CreatedDate - p.ModifiedDate).Minutes) })
           .ToList();

但我收到此错误:

InvalidOperationException:LINQ 表达式 '((EntityShaperExpression:EntityType:票证ValueBufferExpression: (ProjectionBindingExpression: EmptyProjectionMember) IsNullable: False ).CreatedDate - (EntityShaperExpression:EntityType:Tickets ValueBufferExpression: (ProjectionBindingExpression: EmptyProjectionMember) IsNullable: False ).ModifiedDate).Minutes' 无法翻译。要么重写查询的形式,可以 被翻译,或通过插入显式切换到客户端评估 调用 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync()。

我在GroupBy 之后尝试了AsEnumerable(),但GroupBy 似乎无法在客户端执行。需要一个好的方法来解决它。

【问题讨论】:

  • 你试过我的代码了吗?如果以后再遇到同样的问题,可以用这个方法解决。
  • @Yinqiu 我试过你的代码,它解决了我的问题。我非常感谢你。但是在我的场景中不希望使用 AsEnumerable。因此我接受了另一个答案。再次感谢。

标签: asp.net entity-framework linq asp.net-core group-by


【解决方案1】:

可以使用服务端函数DateDiffMinute:

var d = _dbcontext.Tickets
   .Where(m => m.ServiceId != null)
   .GroupBy(t => new { Name = t.Services.Name })
   .Select(m => new { 
       x = m.Key.Name, 
       y = m.Average(p => EF.DbFunctions.DateDiffMinute(p.CreatedDate, p.ModifiedDate)) 
    })
   .ToList();

【讨论】:

    【解决方案2】:

    您会收到此错误,因为从 3.0 开始,EF Core 只允许在客户端评估顶级投影(查询中的最后一个 Select() 调用)中的表达式。

    当查询的任何其他部分中的表达式无法转换为 SQL 或参数时,将引发异常。

    更多详情可以看here

    在你的代码中,AsEnumerable()应该在GroupBy之前使用,像这样:

     var d = _dbcontext.Tickets.Include(m => m.Service)
         .Where(m => m.ServiceId != null).AsEnumerable()
         .GroupBy(t => new { Name = t.Service.Name })
         .Select(m => new { x = m.Key.Name, y = m.Average(p => (p.CreatedDate - p.ModifiedDate).Minutes) })
         .ToList();
    

    结果:

    【讨论】:

      猜你喜欢
      • 2021-09-29
      • 2018-12-15
      • 1970-01-01
      • 2019-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多