Linq 超高添加包括(急加载)到正确位置
我正试图通过添加适当的Include语句来加速我的一些db层函数,以强制快速加载并减少对数据库的查询数量 然而,在90%的情况下,我遇到的问题是,我没有在正确的“起始位置”输入我想要的包含项 我能想到的最简单的例子是: 我有部门、课程和学生实体,它们之间存在多对多关系(下面的一些课程与多个部门) 现在我有一个函数Linq 超高添加包括(急加载)到正确位置,linq,entity-framework-4,eager-loading,Linq,Entity Framework 4,Eager Loading,我正试图通过添加适当的Include语句来加速我的一些db层函数,以强制快速加载并减少对数据库的查询数量 然而,在90%的情况下,我遇到的问题是,我没有在正确的“起始位置”输入我想要的包含项 我能想到的最简单的例子是: 我有部门、课程和学生实体,它们之间存在多对多关系(下面的一些课程与多个部门) 现在我有一个函数 GetMasterCourses(Department dep)哪个功能类似于 return dep.Courses.Where(c=>c.level==“Master”) 问题是:我
GetMasterCourses(Department dep)
哪个功能类似于
return dep.Courses.Where(c=>c.level==“Master”)
问题是:我如何告诉EF加载与每个查询课程相关的所有学生
我找到的唯一解决方案是:
courseIDs = dep.Courses
.Where(c => c.level == "Master").Select(c => c.courseID)
dbcontext.Courses
.Include("Students")
.Where(c => courseIDs.Contains(c.courseID) and c.level == Master)
为了能够指定正确的Include而不得不做这样一个变通方法,这似乎相当愚蠢。我查看了许多包含的示例,并搜索了许多有关stackoverflow的问题,但没有找到有此问题的人,尽管这似乎是一个非常常见的问题。我不明白您为什么选择ID。看起来你可以:
var courses = dep.Courses
.Include(i => i.Students)
.Where(c => c.level == "Master")
.ToList() // or whatever
如果您使用的是
DbContext
(EF>=4.1):
如果将ObjectContext
与EntityObject
派生实体(非POCO)一起使用:
如果将ObjectContext
与POCO一起使用
上述所有查询实际上与您的查询不同,因为您的dep.Courses
集合可能不包含数据库中与部门dep
相关的所有课程。(谁知道加载后您是否没有从dep.Courses
集合中删除课程?)
因为您谈论的是性能和数据库请求优化:如果您想避免再次加载课程(内存中已经有)的开销,您还可以尝试:
courseIDs = dep.Courses
.Where(c => c.level == "Master").Select(c => c.courseID);
var studentDict = dbcontext.Courses
.Where(c => courseIDs.Contains(c.courseID))
.Select(c => new
{
courseID = c.courseID,
Students = c.Students
})
.ToDictionary(x => x.courseID, x => x.Students);
foreach (var course in dep.Courses)
course.Students = studentDict[course.courseID];
它加载的数据更少,但性能不一定更高,因为对于大型
CourseID
集合,Contains
需要大量的转换成SQL的成本。因此,您的输入是部门
,这(我假设)不是上下文的一部分。您期望的返回类型是什么?当您加载部门
时,您是否渴望加载课程
和学生
?部门是函数的参数,例如由dbcontext.Departments.First()检索。在这段时间里,课程和学生们确实不感兴趣。预期的返回类型将是IQueryable,因此一组课程将加载相关的学生集合。dep.courses.Include(i=>i.Students)
正是我想要做的,但EF不允许这样做。似乎我是ObjectQuery对象(即context.Courses)上唯一的一个包含。我不能在IQueryable类关联集(dep.Courses)上使用include函数。我使用的是EF4而不是EF5,但我在互联网上还没有看到一个能像这样使用include的例子。如果可能的话,请告诉我。
objectContext.Departments.Attach(dep);
dep.Courses.Attach(dep.Courses.CreateSourceQuery()
.Include("Students")
.Where(c => c.level == "Master")
.ToList());
courseIDs = dep.Courses
.Where(c => c.level == "Master").Select(c => c.courseID);
var studentDict = dbcontext.Courses
.Where(c => courseIDs.Contains(c.courseID))
.Select(c => new
{
courseID = c.courseID,
Students = c.Students
})
.ToDictionary(x => x.courseID, x => x.Students);
foreach (var course in dep.Courses)
course.Students = studentDict[course.courseID];