LINQ 嵌套 select 导致多个 SQL 查询

LINQ nested select causes multiple SQL queries

我正在尝试检索包含(作为每门课程的 属性)部门列表的课程列表。数据库模式由课程、部门和 course_departments 连接 table.

组成

我当前的查询(删除了不必要的位)如下:

ctx.Courses
    .Select(c => new Course
        {
            ID = c.ID,
            Departments = c.CourseDepartments.Select(cd => new Department(cd.Department))
        }
     )

这行得通,但在探查器中进行检查后,它正在执行新查询以获取每门课程的部门。如何编写此查询以将其作为单个 SQL 查询执行?

因为您使用嵌套的 select,SQL 提供程序将其转换为等效的 SQL(使用 separate/nested 查询)。您可以像这样使用 Join 方法更正此问题;

ctx.Courses.Join(ctx.CourseDepartments,
                 c => c.ID, cd => cd.cID,
                 (c, cd) => new {
                     Course = c,
                     dID = cd.dID
                 }).Join(ctx.Departments,
                         c => c.dID,
                         d => d.ID,
                         (c, d) => new {
                               Course = c.Course,
                               Department = d
                 });

我没有测试示例代码,但这是基本思路。我几乎完全使用方法语法,但查询语法实际上对于连接来说更清晰,你可以在这里比较它们 How do I convert multiple inner joins in SQL to LINQ? 这是我用来制作我的解决方案的方法。

总结问题原因及解决办法;如果你想要一个查询,你必须从课程到课程部门再到部门,SQL 提供者不能暗示你的嵌套 select 应该被翻译成一对连接。要在 LINQ 中编写查询,您应该使用最相似的可用 SQL 结构,在本例中为连接。可能还有其他方式来编写查询,这些查询将隐式通知查询提供程序连接,但这是编写您想要的查询的显式方式。

我编写了一些可能适合您的解决方案的代码。 实体定义不完全相同,但事实并非如此。

var query = context.Courses.AsQueryable();
query = query.Include(i => i.CoursesDepartments);
query = query.Include(i => i.CoursesDepartments.Select(cd => cd.Departments));

var newQuery = query.Select(course =>  new 
{
    ID = course.ID,
    Departments = course.CoursesDepartments.Select( cd => cd.Departments),
});

var result = query.ToList();

简而言之,Include 函数告诉 LINQ 在获取课程实体时应该加载哪些相关实体,否则它们将被延迟加载。

提示:我知道有些人使用 LINQPad 来学习 LINQ,也许这对你将来有帮助。