【发布时间】:2020-01-23 17:45:31
【问题描述】:
我已经学会了在 EF Core 3.0 中,客户端评估 can only happen on the top level projection(即最后一次调用 Select)。我以为我理解了这个问题,但是在 3.1 下一个查询的失败告诉我我不知道。
这是查询
using (var ctx = new GsContext())
{
var recs = ctx.Calibrations
.Where(ca => ca.DeviceId == deviceId)
.AsNoTracking()
.Include(c => c.Cartridge)
.OrderByDescending(i => i.CalibratedOn)
.GroupBy(r => r.CartridgeId)
.Select(q => q.First())
.ToList();
我没有看到自己在做任何复杂的预测或任何需要在 Select 之前进行客户端评估的事情,所以异常消息让我感到困惑。这是错误消息的文本:
LINQ 表达式'(GroupByShaperExpression: KeySelector: (c.CartridgeId), ElementSelector:(EntityShaperExpression: 实体类型:校准 值缓冲区表达式: (ProjectionBindingExpression:EmptyProjectionMember) IsNullable: 假 ) ) .First()' 无法翻译。要么以可翻译的形式重写查询,要么显式切换到客户端评估 通过插入对 AsEnumerable()、AsAsyncEnumerable() 的调用, ToList() 或 ToListAsync()。看 https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。
之前,当我的查询试图在查询的早期进行一些复杂的字符串处理时,我已经遇到过这样的异常(就像我说的,我很难了解这个问题),但这里的情况并非如此,至少我看不到。
我找到了this related question,但在这种情况下,这个人正在 GroupBy 子句中进行投影。我不这样做。
如果有帮助,这里是校准类
public class Calibration
{
[Key]
[Required]
public int Id { get; set; }
[Required]
public int DeviceId { get; set; }
[Required]
public int CartridgeId { get; set; }
[ForeignKey(nameof(CartridgeId))]
public Cartridge Cartridge { get; set; }
public DateTime CalibratedOn { get; set; }
}
我确信我可以解决这个问题。我要求更好地理解客户端/服务器评估。有人可以向我解释我错过了什么吗?我的查询需要客户评估吗
【问题讨论】:
-
我很好奇这是否与在分组之前排序有关(分组必须保留 linq-to-object 的顺序,但其他实现,例如 EF,可能不需要这样做所以)。我会试试这个:
ctx.Calibrations.Where(ca => ca.DeviceId == deviceId).AsNoTracking().Include(c => c.Cartridge).GroupBy(r => r.CartridgeId).Select(q => q.OrderByDescending(i => i.CalibratedOn).First()).ToList(); -
感谢尝试,但不幸的是没有帮助。它确实改变了异常中的错误消息。现在它说 OrderByDescending(i => i.CalibratedOn) 无法翻译
标签: entity-framework-core entity-framework-core-3.1