EF Core 2.1 RC 1 GroupBy仍然在本地进行评估

Gio*_*zas 6 c# entity-framework-core .net-core

我按照ASP.NET博客的官方指南将ASP.NET Core项目从2.0.x升级到2.1.0-rc1.该EF核心软件包进行了更新,以相同的版本,以及.我使用的数据库提供程序是Microsoft.EntityFrameworkCore.SqlServer.我正在等待这次升级,因为我需要很多LINQ GroupBy翻译功能.我的一个疑问如下:

await _db.Documents
         .ApplyFilter(options)
         .Where(x => x.SubscriptionId == subscriptionId && x.Status != DocumentStatus.Deleted)
         .GroupBy(document => new { document.SubscriptionId })
         .Select(group => new {
            Total = group.Sum(x => x.Total),
            TotalDiscount = group.Sum(x => x.TotalDiscount),
            TotalNet = group.Sum(x => x.TotalNet != null ? x.TotalNet.Value * (decimal)x.CurrencyRate : 0),
            SubTotal = group.Sum(x => x.SubTotal != null ? x.SubTotal.Value * (decimal)x.CurrencyRate : 0),
            TotalSalesTax = group.Sum(x => x.TotalSalesTax != null ? x.TotalSalesTax.Value * (decimal)x.CurrencyRate : 0),
            TotalTax = group.Sum(x => x.TotalTax != null ? x.TotalTax.Value * (decimal)x.CurrencyRate : 0),
            TotalPayable = group.Sum(x => x.TotalPayable != null ? x.TotalPayable.Value * (decimal)x.CurrencyRate : 0)
        })
        .ToListAsync();
Run Code Online (Sandbox Code Playgroud)

当此查询运行时,我仍会收到一条警告,指出:

EFCore Linq查询无法翻译,将在本地进行评估.

所以我想问一下,如果我做某事(非常)错了或者这个功能还没有公布,那么这个功能还没有?你有没有尝试过类似的东西?预先感谢您的帮助.


编辑

对于测试的摇晃问题,尝试了以下查询(从Sum方法中删除了条件检查),如Ivan Stoev在评论中建议的那样,但结果是一样的.

await _db.Documents
         .ApplyFilter(options)
         .Where(x => x.SubscriptionId == subscriptionId && x.Status != DocumentStatus.Deleted)
         .GroupBy(document => new { document.SubscriptionId })
         .Select(group => new {
            Total = group.Sum(x => x.Total),
            TotalDiscount = group.Sum(x => x.TotalDiscount),
            TotalNet = group.Sum(x => x.TotalNet),
            SubTotal = group.Sum(x => x.SubTotal),
            TotalSalesTax = group.Sum(x => x.TotalSalesTax),
            TotalTax = group.Sum(x => x.TotalTax),
            TotalPayable = group.Sum(x => x.TotalPayable)
          })
          .ToListAsync();
Run Code Online (Sandbox Code Playgroud)

解

经过实验,我发现了以下几点.我发布它以防有人有同样的问题.以下查询完美地转换为T-SQL语句,因此不在客户端上进行评估.

await (from d in _db.Documents.ApplyFilter(options)
       where d.SubscriptionId == subscriptionId && d.Status != DocumentStatus.Deleted
       group d by d.SubscriptionId into g
       select new {
          Total = g.Sum(x => x.Total/* * Convert.ToDecimal(x.CurrencyRate)*/),
          TotalDiscount = g.Sum(x => x.TotalDiscount/* * Convert.ToDecimal(x.CurrencyRate)*/),
          TotalNet = g.Sum(x => x.TotalNet/* * Convert.ToDecimal(x.CurrencyRate)*/),
          SubTotal = g.Sum(x => x.SubTotal/* * Convert.ToDecimal(x.CurrencyRate)*/),
          TotalSalesTax = g.Sum(x => x.TotalSalesTax/* * Convert.ToDecimal(x.CurrencyRate)*/),
          TotalTax = g.Sum(x => x.TotalTax/* * Convert.ToDecimal(x.CurrencyRate)*/),
          TotalPayable = g.Sum(x => x.TotalPayable/* * Convert.ToDecimal(x.CurrencyRate)*/)
       }).ToListAsync();
Run Code Online (Sandbox Code Playgroud)

明显的区别是我使用LINQ查询语法而不是扩展方法.此外,我注释了与CurrencyRate属性的乘法,因为它也导致在本地评估查询.这看起来很奇怪,因为查询语法也可以在扩展方法中进行翻译.

我还在Entity Framework Core的Github存储库中打开了一个问题,你可以在这里找到它

Jes*_*per 0

GroupBy 是一个转移注意力的话题。

使用查询语法编译为使用扩展方法,所以这不是问题。

我在编辑中的版本和查询语法中的版本之间看到的唯一区别是,您_db.Documents.ApplyFilter(...)在仍本地评估 group by 的情况下执行此操作。我猜测这会导致返回类型转换为其他类型,并选择错误的重载,或者一些使查询翻译器感到困惑的类似细节 - 这将导致所有LINQ 运算符(Where、Select、GroupBy 等) ) 进行本地评估。