这是我的表达:
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子句它工作正常,但我想过滤掉已删除的模块。
答案 0 :(得分:12)
.Include
用于从数据库中急切加载相关实体。即在您的情况下,确保模块和实验室的数据已加载课程。
.Include
中的lamba表达式应该告诉Entity Framework要包含哪个相关表。
在你的情况下,你也试图在include中执行一个条件,这就是你收到错误的原因。
看起来您的查询是这样的:
找到与给定ID匹配的课程,以及相关模块和实验室。只要不删除匹配模块和章节。
如果这是对的,那么这应该有效:
Course course = db.Courses.Include(c => c.Modules)
.Include(c => c.Lab)
.Single(c => c.Id == id &&
!c.Module.IsDeleted &&
!c.Chapter.IsDeleted);
答案 1 :(得分:4)
但为什么会导致错误?
我可以想象,有时EF团队会在他们引入这种Include
语法的那一天感到遗憾。 lambda表达式表明任何有效的linq表达式都可以用于巧妙地操纵急切加载。但太糟糕了,不是这样。正如我解释here,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
command的上下文中预加载课程中未删除的模块和章节。关系修正将填充正确的导航属性。 Include
的{{1}}将正常工作。
顺便说一下,此功能有change request。