【发布时间】:2020-06-16 22:02:07
【问题描述】:
我已经为此苦苦挣扎了四天,但一点进展都没有。 有一个查询,在更新到 EF Core 3.1 之前工作得很好:
var equipments = await this.DbContext.ServContrObjStructEquipment
.AsNoTracking()
.Where(e => e.ServContrObjStruct.ServContrObjStructParent.ServContrObjStructParent.Objectuuid == sectionGuid)
.Where(e => e.ServContrObjStructPlanEquipment.Select(x => x.PkServContrObjStructPlanEquipment).Contains(
e.ServContrObjStructPlanEquipment.OrderByDescending(x => x.ServContrObjStructPlanVers.ActiveUntil ?? DateTime.MaxValue).ThenByDescending(x => x.ServContrObjStructPlanVers.ActiveFrom).ThenByDescending(x => x.ActiveFrom).Select(x => x.PkServContrObjStructPlanEquipment).FirstOrDefault()
))
现在它向我抛出一个异常,上面写着:
LINQ 表达式 'DbSet .Where(s3 => s3.RecStatus == 1) .Where(s3 => EF.Property>((EntityShaperExpression: 实体类型:ServContrObjStructEquipment 值缓冲区表达式: (ProjectionBindingExpression:Outer.Outer.Outer) IsNullable: False ), "PkServContrObjStructEquipment") != null && EF.Property>((EntityShaperExpression: 实体类型:ServContrObjStructEquipment 值缓冲区表达式: (ProjectionBindingExpression:Outer.Outer.Outer) IsNullable: False ), "PkServContrObjStructEquipment") == EF.Property>(s3, "FkServContrObjStructEquipment")) .Select(s3 => s3.PkServContrObjStructPlanEquipment) .Contains((MaterializeCollectionNavigation( 导航:导航:ServContrObjStructEquipment.ServContrObjStructPlanEquipment, 子查询:DbSet .Where(s4 => s4.RecStatus == 1) .Where(i => EF.Property>((EntityShaperExpression: 实体类型:ServContrObjStructEquipment 值缓冲区表达式: (ProjectionBindingExpression:Outer.Outer.Outer) IsNullable: 假 ), "PkServContrObjStructEquipment") != null && EF.Property>((EntityShaperExpression: 实体类型:ServContrObjStructEquipment 值缓冲区表达式: (ProjectionBindingExpression:Outer.Outer.Outer) IsNullable: 假 ), "PkServContrObjStructEquipment") == EF.Property>(i, "FkServContrObjStructEquipment"))) .AsQueryable() .OrderByDescending(x => x.ServContrObjStructPlanVers.ActiveUntil ?? 12/31/9999 11:59:59 PM) .ThenByDescending(x => x.ServContrObjStructPlanVers.ActiveFrom) .ThenByDescending(x => x.ActiveFrom) .Select(x => x.PkServContrObjStructPlanEquipment) .FirstOrDefault())' 无法翻译。要么以可翻译的形式重写查询,要么切换到客户评估 通过插入对 AsEnumerable() 的调用,显式地 AsAsyncEnumerable()、ToList() 或 ToListAsync()。看 https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。
我知道 EF Core 3.0-3.1 有重大更改,并且客户端评估现在在顶级 Select() 上执行。虽然我宁愿避免这样做,但我尝试调用所有ToList()、AsEnumerable() 等来使其工作,但这也无济于事:查询复杂且多级,所以调用ToList()在任何时候,要么破坏它,要么没有得到相关记录(我猜是因为延迟加载),然后需要进一步执行查询。
我还尝试将查询拆分为单独的查询,看看那里发生了什么:
var intermEquipments = await this.DbContext.ServContrObjStructEquipment
.AsNoTracking()
.Include(e => e.ServContrObjStructPlanEquipment)
.Where(e=>e.ServContrObjStruct.ServContrObjStructParent.ServContrObjStructParent.Objectuuid == sectionGuid)
.ToListAsync();
var intermEquipments1 = await this.DbContext.ServContrObjStructEquipment
.AsNoTracking()
.Include(e => e.ServContrObjStructPlanEquipment)
.Where(e => e.ServContrObjStruct.ServContrObjStructParent.ServContrObjStructParent.Objectuuid == sectionGuid)
.Select(e => e.ServContrObjStructPlanEquipment.Select(x => x.PkServContrObjStructPlanEquipment))
.ToListAsync();
var intermEquipments2 = this.DbContext.ServContrObjStructEquipment
.AsNoTracking()
.Include(e => e.ServContrObjStructPlanEquipment)
.Where(e => e.ServContrObjStruct.ServContrObjStructParent.ServContrObjStructParent.Objectuuid == sectionGuid)
.Select(e => e.ServContrObjStructPlanEquipment
.OrderByDescending(x => x.ServContrObjStructPlanVers.ActiveUntil ?? DateTime.MaxValue)
.ThenByDescending(x => x.ServContrObjStructPlanVers.ActiveFrom)
.ThenByDescending(x => x.ActiveFrom)
.Select(x => x.PkServContrObjStructPlanEquipment).ToList());
但它要么给我抛出一个异常,说
Include 中使用的 Lambda 表达式无效
或 NullReference(因为某些相关属性没有加载,正如我上面提到的)或根本不显示记录。
虽然我不是专家,但我对 EntityFramework 很熟悉。有没有办法重写这个查询,以便它可以被翻译或者只是做任何事情让它工作? 谢谢!
【问题讨论】:
-
为什么需要在拆分查询中包含。你有 this.NextreeContext.ServContrObjStructEquipment 和 .Include(e => e.ServContrObjStructPlanEquipment)。正因为您没有收到编译器错误,编译器正在识别对象 ServContrObjStructEquipment 并且您不需要包含。
-
看起来问题出在两个
Where表达式之一。最有可能是第二个,但为了确定,先评论他们两个,然后取消评论其中一个,等等,直到你得到例外。 -
这对我来说似乎有点奇怪。将那些 where 语句变成连接不是更好吗?
-
@IvanStoev 问题出在
Contains表达式上,请确认。 -
@Mike-314 你把它们变成连接是什么意思?
标签: c# entity-framework linq asp.net-core ef-core-3.1