【发布时间】:2019-04-23 17:37:06
【问题描述】:
我按照 ASP.NET 博客中的 official guide 将 ASP.NET Core 项目从版本 2.0.x 升级到 2.1.0-rc1。 EF Core 包也更新到了相同的版本。我使用的数据库提供程序是Microsoft.EntityFrameworkCore.SqlServer。我期待着这次升级,因为我需要很多LINQ GroupBy translation 功能。我的查询之一如下:
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();
当这个查询运行时,我仍然会收到一条警告:
EFCore Linq 查询无法翻译,将在本地进行评估。
所以我想问一下我是否做错了什么(非常)或者这个功能还没有像宣传的那样可用?你们中有人尝试过类似的东西吗?提前感谢您的帮助。
编辑
为了测试问题,尝试了以下查询(从 Sum 方法中删除了条件检查),正如 cmets 中所建议的 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();
解决方案
经过实验,我发现了以下内容。我发布它以防有人遇到同样的问题。以下查询完美地转换为 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();
明显的区别是我使用 LINQ 查询语法 而不是 扩展方法。此外,我将 CurrencyRate 属性的乘法注释为 它也会导致在本地评估查询。这似乎很奇怪,因为查询语法也可以转换为引擎盖下的扩展方法。
我还在 Entity Framework Core 的 Github 存储库中打开了一个问题 你可以找到here
【问题讨论】:
-
你甚至没有告诉你正在使用哪个提供商
-
您能否向我们展示一个不会生成该警告的类似查询(没有
GroupBy),以便我们比较两者? -
@Tseng 我编辑了帖子。我正在使用Microsoft.EntityFrameworkCore.SqlServer(所以我使用的是 Sql Server)。
-
离题,
x.TotalNet != null ? x.TotalNet.Value * (decimal)x.CurrencyRate : 0可以缩短为(x.TotalNet ?? 0) * (decimal)x.CurrencyRate。我也不确定(decimal)在这里是否有用。这也可能涉及 EF Core 无法翻译您的 linq 查询但我尚未确认的原因。
标签: c# .net-core entity-framework-core