我刚刚升级到 EF 3,曾经有效的查询之一现在出现异常
ProductionRecords = _context.ProductionRecords
.Where(r => r.DataCriacao.Date == DateTime.Now.Date)
.Select(pr => new ProductionRecordViewModel
{
Id = pr.Id,
Operador = pr.Operador,
DataCriacao = pr.DataCriacao,
Celula = pr.Celula.Name,
Turno = pr.Turno.Name,
TotalPecasSemDefeito = pr.ReferenceRecords.Sum(c => c.Quantity),
TotalPecasComDefeito = pr.DefectRecords.Sum(c => c.Quantidade),
TotalTempoParado = pr.StopRecords.Sum(c => Convert.ToInt32(c.Duration.TotalMinutes)),
})
.AsNoTracking()
.ToList();
当我试图将集合与时间跨度和持续时间相加时,就会发生异常......
我现在该怎么处理这个问题?
这是例外
InvalidOperationException:LINQ 表达式
'(EntityShaperExpression: EntityType: StopRecord
ValueBufferExpression:(ProjectionBindingExpression:
EmptyProjectionMember) IsNullable: False ).Duration.TotalMinutes'
无法翻译。要么以可以的形式重写查询
被翻译,或通过插入显式切换到客户评估
调用 AsEnumerable()、AsAsyncEnumerable()、ToList() 或
ToListAsync()。看https://go.microsoft.com/fwlink/?linkid=2101038为了
更多信息。
EF3 中有一个重大更改,除非在查询链的最后(您的查询链的最后),否则不会自动恢复到客户端评估Convert.ToInt32(c.Duration.TotalMinutes)
可能依赖)。
尝试像这样重写您的查询:
ProductionRecords = _context.ProductionRecords
.Where(r => r.DataCriacao.Date == DateTime.Now.Date)
.AsNoTracking()
.AsEnumerable()
.Select(pr => new ProductionRecordViewModel
{
Id = pr.Id,
Operador = pr.Operador,
DataCriacao = pr.DataCriacao,
Celula = pr.Celula.Name,
Turno = pr.Turno.Name,
TotalPecasSemDefeito = pr.ReferenceRecords.Sum(c => c.Quantity),
TotalPecasComDefeito = pr.DefectRecords.Sum(c => c.Quantidade),
TotalTempoParado = pr.StopRecords pr.StopRecords.Sum(c => Convert.ToInt32(c.Duration.TotalMinutes)),
})
.ToList();
UPD正如评论中正确指出的那样 - 这基本上会推迟.Select
给客户端评价。这可能会导致性能问题。这种行为很可能是对 EF Core 3 进行此更改的首要原因。
我没有足够的细节来向您推荐合适的解决方案,但看来您无法真正摆脱加载StopRecords
关于你所有的结果。这就是编写自定义方法翻译器可以为您提供帮助的地方。看我的其他答案关于如何做到这一点。我快速检查了 EF Core 3 源代码,看起来IMethodCallTranslator仍然在那里。这意味着您很有可能构建一个自定义函数,将日期转换为 SQL 中的 TotalMinutes。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)