【问题标题】:Why there is no GroupBy clause in internal SQL of Entity Framework linq query?为什么Entity Framework linq查询的内部SQL中没有GroupBy子句?
【发布时间】:2020-07-10 09:16:29
【问题描述】:

在实体框架的文档中: https://www.entityframeworktutorial.net/querying-entity-graph-in-entity-framework.aspx

在有关 GroupBy 的部分中,我们可以阅读以下代码:

using (var ctx = new SchoolDBEntities())
{    
    var students = from s in ctx.Students 
                group s by s.StandardId into studentsByStandard
                select studentsByStandard;

    foreach (var groupItem in students)
    {
        Console.WriteLine(groupItem.Key);

        foreach (var stud in groupItem)
        {
            Console.WriteLine(stud.StudentId);
        }
    }
}

在内部执行以下 SQL:

SELECT 
[Project2].[C1] AS [C1], 
[Project2].[StandardId] AS [StandardId], 
[Project2].[C2] AS [C2], 
[Project2].[StudentID] AS [StudentID], 
[Project2].[StudentName] AS [StudentName], 
[Project2].[StandardId1] AS [StandardId1]
FROM ( SELECT 
    [Distinct1].[StandardId] AS [StandardId], 
    1 AS [C1], 
    [Extent2].[StudentID] AS [StudentID], 
    [Extent2].[StudentName] AS [StudentName], 
    [Extent2].[StandardId] AS [StandardId1], 
    CASE WHEN ([Extent2].[StudentID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
    FROM   (SELECT DISTINCT 
        [Extent1].[StandardId] AS [StandardId]
        FROM [dbo].[Student] AS [Extent1] ) AS [Distinct1]
    LEFT OUTER JOIN [dbo].[Student] AS [Extent2] ON ([Distinct1].[StandardId] = [Extent2].                                                [StandardId]) OR (([Distinct1].[StandardId] IS NULL) AND ([Extent2].[StandardId] IS NULL))
)  AS [Project2]
ORDER BY [Project2].[StandardId] ASC, [Project2].[C2] ASC
go

为什么 SQL 中没有 GroupBy 子句?如果不需要 GroupBy 子句,我们不能只使用带 OrderBy 且不带 Join 的简单 Select 吗?谁能解释一下上面的查询?

【问题讨论】:

    标签: c# sql entity-framework group-by entity-framework-6


    【解决方案1】:

    底线是:因为 SQL 不能返回嵌套的结果集。

    每个 SQL SELECT 语句都返回一个平面的值列表。 LINQ 能够返回对象图,即具有嵌套对象的对象。这正是 LINQ 的 GroupBy 所做的。

    在 SQL 中,GROUP BY 语句只返回分组列和聚合结果:

    SELECT StandardId, COUNT(*)
    FROM Students
    GROUP BY StandardId;
    

    其余的学生栏目都不见了。

    LINQ GroupBy 语句返回类似

    StandardId
                StudentId StudentName
    1
                21        "Student1"
                15        "Student2"
    2
                48        "Student3"
                91        "Student4"
                17        "Student5"
    

    因此,SQL GROUP BY 语句永远不能成为 LINQ GroupBy 的来源。

    Entity Framework (6) 知道这一点,它会生成一条 SQL 语句,从数据库中提取所有需要的数据,添加一些使分组更容易的部分,并在客户端创建分组。

    【讨论】:

    • 但是为什么我们不能只做一个没有 Joins 和 OrderBy 的简单 Select 呢?
    • 因为“我们”什么都不做 :)。我认为创建这种查询是 EF 的决定,因为它保证可以在客户端创建组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    相关资源
    最近更新 更多