EF Lambda:包含路径表达式必须引用导航属性[重复]
Posted
技术标签:
【中文标题】EF Lambda:包含路径表达式必须引用导航属性[重复]【英文标题】:EF Lambda: The Include path expression must refer to a navigation property [duplicate] 【发布时间】:2013-04-05 12:43:19 【问题描述】:这是我的表达:
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 子句,它可以正常工作,但我想过滤掉已删除的模块。
【问题讨论】:
【参考方案1】:.Include
用于从数据库中急切地加载相关实体。 IE。在您的情况下,请确保课程中加载了模块和实验室的数据。
.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);
【讨论】:
这确实是错误的。您将从模块和实验室表中获取所有项目。【参考方案2】:但是为什么会导致错误呢?
我可以想象,有时 EF 团队会后悔他们引入这种 Include
语法的那一天。 lambda 表达式表明,任何有效的 linq 表达式都可以用来巧妙地操纵预加载。但太糟糕了,并非如此。正如我在here 解释的那样,lambda 仅用作底层“真实”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
command 预加载上下文中未删除的课程模块和章节。关系修复将填充正确的导航属性。 Lab
的Include
将正常工作。
顺便说一句,这个功能有一个change request。
【讨论】:
以上是关于EF Lambda:包含路径表达式必须引用导航属性[重复]的主要内容,如果未能解决你的问题,请参考以下文章
包含路径表达式必须引用 type.in 预加载中定义的导航属性
包含路径表达式必须引用在类型上定义的导航属性(使用 LINQ 选择数据)
Include 中使用的 Lambda 表达式无效。 EF6,导航属性