Include路径表达式必须引用一个导航属性
本文关键字:一个 导航 属性 路径表达式 引用 Include | 更新日期: 2023-09-27 18:08:49
我的表达式:
Course course = db.Courses
.Include(
i => i.Modules.Where(m => m.IsDeleted == false)
.Select(s => s.Chapters.Where(c => c.IsDeleted == false))
).Include(i => i.Lab).Single(x => x.Id == id);
我知道原因是Where(m => m.IsDeleted == false)
在模块部分,但为什么它会导致错误?更重要的是,我该如何修复它?
如果我删除where子句,它工作得很好,但我想过滤掉删除的模块。
.Include
用于从数据库中主动加载相关实体。也就是说,在你的情况下,确保模块和实验的数据与课程一起加载。
.Include
中的lamba表达式应该告诉实体框架包含哪个相关表。
在您的情况下,您还试图在包含中执行条件,这就是您收到错误的原因。
看起来你的查询是这样的:
查找与给定id匹配的课程,包含相关模块和实验。只要不删除匹配的模块和章节。
如果这是正确的,那么这个应该可以工作:
Course course = db.Courses.Include(c => c.Modules)
.Include(c => c.Lab)
.Single(c => c.Id == id &&
!c.Module.IsDeleted &&
!c.Chapter.IsDeleted);
为什么会导致错误呢?
我可以想象有时EF团队会后悔他们引入了这个Include
语法。lambda表达式表明,可以使用任何有效的linq表达式巧妙地操纵即时加载。但遗憾的是,事实并非如此。正如我在这里解释的那样,lambdas只是作为底层"真正的"Include
方法的伪装字符串参数。
我如何修复它?
最好是投影到另一个类(比如,DTO)
db.Courses.Select(x => new CourseDto {
Id = x.Id,
Lab = x.Lab,
Modules = x.Modules.Where(m => !m.IsDeleted).Select( m => new ModuleDto {
Moudle = m,
Chapters = x.Chapters.Where(c => c.IsDeleted)
}
}).Single(x => x.Id == id);
但这对你来说可能是一个重大的修改。
另一个选项是通过Load
命令在上下文中禁用延迟加载和预加载课程的未删除模块和章节。关系修复将填充右边的导航属性。Lab
的Include
将正常工作
顺便说一下,这个特性有一个变更请求