0

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

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

我能想到的最简单的例子:

我有DepartmentCourseStudent实体,它们之间存在多对多关系(下面的一些课程涉及多个部门)。

现在我有一个功能

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 上搜索了许多问题,但实际上找不到遇到此问题的任何人,尽管这似乎是一个很常见的问题。

4

2 回答 2

1

If you are using 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();

If you are using ObjectContext with EntityObject derived entities (not POCOs):

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

If you are using ObjectContext with POCOs it's possible but a bit hairy.

All queries above are actually not the same like yours because maybe your dep.Courses collection does not contain all the courses that are related to the department dep in the database. (Who knows if you didn't remove a course from the dep.Courses collection after loading it?) In this case I'm afraid your query is the only way to go.

Because you were talking about performance and database request optimization: If you want to avoid the overhead to load the courses again (which you already have in memory) you could also try:

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];

It loads less data but is not necessarily more performant because Contains has significant costs of translation into SQL for large courseIDs collections.

于 2013-06-27T18:49:01.050 回答
1

我不明白您为什么要选择 ID。看起来你可以:

var courses = dep.Courses
  .Include(i => i.Students)
  .Where(c => c.level == "Master")
  .ToList() // or whatever
于 2013-06-26T17:42:59.437 回答