无法添加包含(急切加载)以纠正错误的位置

时间:2013-06-26 17:21:31

标签: linq entity-framework-4 eager-loading

我正在尝试通过添加适当的Include语句来加速我的数据库层功能,以强制执行加载并减少我对数据库进行的查询次数。

然而,在90%的情况下,我遇到的问题是我没有在正确的“起始位置”进入我想要的包含。

我能提出的最简单的例子:

我有部门课程学生实体,他们之间有多对多关系(以下某些课程涉及多个部门)。

现在我有一个功能

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,必须做这样的解决方案似乎很愚蠢。我已经看了很多关于Include的例子,并在stackoverflow上搜索了很多问题,但是找不到任何有这个问题的人,尽管这似乎是一个很常见的问题。

2 个答案:

答案 0 :(得分:1)

我不明白为什么要选择ID。看起来你可能只是:

var courses = dep.Courses
  .Include(i => i.Students)
  .Where(c => c.level == "Master")
  .ToList() // or whatever

答案 1 :(得分:1)

如果您使用DbContext(EF> = 4.1):

dbContext.Departments.Attach(dep);
dep.Courses = dbContext.Entry(dep).Collection(d => d.Courses).Query()
    .Include(c => c.Students)
    .Where(c => c.level == "Master")
    .ToList();

如果您将ObjectContextEntityObject派生实体(非POCO)一起使用:

objectContext.Departments.Attach(dep);
dep.Courses.Attach(dep.Courses.CreateSourceQuery()
    .Include("Students")
    .Where(c => c.level == "Master")
    .ToList());

如果您将ObjectContext与POCO it's possible but a bit hairy一起使用。

上述所有查询实际上与您的查询不同,因为您的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];

它加载的数据较少,但不一定具有更高的性能,因为Contains会为大型courseIDs集合转换成SQL的成本很高。