我有一个带有EntityFramework的.Net Core 2.2项目,以及一个具有许多嵌套属性(无论是单个对象还是集合)的模型。
我已经启用了延迟加载,现在我只想选择性地加载我在控制器中已插入的对象树的部分。
当我使用.include()时,一切都很好,直到我想包含一个集合属性,并且对于该集合中的每个项目,我都想包含一个相关实体。
阅读文档时,我使用了这种方法:
var mainObj = _db.MyEntityA.AsNoTracking()
.Include(e => e.MyEntityB)
.Include(e => e.CollectionOfEntityC.Select((MyEntityC ce) => ce.MyEntityD))
当我运行它时,它会给出如下信息:
InvalidOperationException: The Include property lambda expression 'e => {from EntityC ce in e.CollectionOfEntityC select [ce].MyEntityD}' is invalid. The expression should represent a property access: 't => t.MyProperty'. To target navigations declared on derived types, specify an explicitly typed lambda parameter of the target type, E.g. '(Derived d) => d.MyProperty'.
所以我尝试添加演员表:
var mainObj = _db.MyEntityA.AsNoTracking()
.Include(e => e.MyEntityB)
.Include(e => e.CollectionOfEntityC.Select((MyEntityC ce) => ce.MyEntityD))
但没有任何改变。
我尝试通过这种方式使用.ThenInclude():
var mainObj = _db.MyEntityA.AsNoTracking()
.Include(e => e.MyEntityB)
.ThenInclude(e => e.Select((MyEntityC ce) => ce.MyEntityD))
有无演员表都没有改变。
最后,合理地讲,如果删除该导航属性,则会出现以下异常:
Error generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingWarning: An attempt was made to lazy-load navigation property 'MyEntityD' on detached entity of type 'MyEntityCProxy'. Lazy-loading is not supported for detached entities or entities that are loaded with 'AsNoTracking()'.
我正在移植到.Net Core上的同一场景,在.Net Framework EF上按预期工作。
编辑:
探索正确提及的重复项,我只想添加一些其他相关方面。
@StriplingWarrior的回答很好;我使用.ThenInclude()而不是.Select()修复了我的代码。现在一切都建立了,但是:
AsNoTraking()
,则必须禁用DetachedLazyLoadingWarning
AsNoTracking()
EF跟踪更改,我不希望它跟踪(我想要一个复杂对象的只读快照)答案 0 :(得分:2)
It looks like这就是您应该使用ThenInclude
的方式:
var mainObj = _db.MyEntityA.AsNoTracking()
.Include(e => e.MyEntityB)
.Include(e => e.CollectionOfEntityC)
.ThenInclude(ce => ce.MyEntityD);