c# - EF LINQ 翻译 : complex query

标签 c# entity-framework linq group-by

我有这段代码(注意 l.FirstOrDefault().Name):

    var qry = from peron in db.Persons
    join room in db.Rooms on peron.Room.Id equals room.Id
    join passport in db.Passports on peron.Passport.Id equals passport.Id
    select new {peron.Fio, room.Name, passport.Number, Count = 0};
    qry = qry.GroupBy(l => new {l.Fio, l.Number})
          .Select(l => new {
                               l.Key.Fio, 
                               l.FirstOrDefault().Name, 
                               l.Key.Number, 
                               Count = l.Count()
                            });

这转化为:

SELECT 
        1 AS [C1], 
        [Project4].[Fio] AS [Fio], 
        [Project4].[C1] AS [C2], 
        [Project4].[Number] AS [Number], 
        [Project4].[C2] AS [C3]
        FROM ( SELECT 
            [Project3].[Fio] AS [Fio], 
            [Project3].[Number] AS [Number], 
            [Project3].[C1] AS [C1], 
            (SELECT 
                COUNT(1) AS [A1]
                FROM  [dbo].[People] AS [Extent6]
                INNER JOIN [dbo].[Passports] AS [Extent7] ON [Extent6].[Passport_Id] = [Extent7].[Id]
                WHERE ([Extent6].[Room_Id] IS NOT NULL) AND (([Project3].[Fio] = [Extent6].[Fio]) OR (([Project3].[Fio] IS NULL) AND ([Extent6].[Fio] IS NULL))) AND (([Project3].[Number] = [Extent7].[Number]) OR (([Project3].[Number] IS NULL) AND ([Extent7].[Number] IS NULL)))) AS [C2]
            FROM ( SELECT 
                [Distinct1].[Fio] AS [Fio], 
                [Distinct1].[Number] AS [Number], 
                (SELECT TOP (1) 
                    [Extent4].[Name] AS [Name]
                    FROM   [dbo].[People] AS [Extent3]
                    INNER JOIN [dbo].[Rooms] AS [Extent4] ON [Extent3].[Room_Id] = [Extent4].[Id]
                    INNER JOIN [dbo].[Passports] AS [Extent5] ON [Extent3].[Passport_Id] = [Extent5].[Id]
                    WHERE (([Distinct1].[Fio] = [Extent3].[Fio]) OR (([Distinct1].[Fio] IS NULL) AND ([Extent3].[Fio] IS NULL))) AND (([Distinct1].[Number] = [Extent5].[Number]) OR (([Distinct1].[Number] IS NULL) AND ([Extent5].[Number] IS NULL)))) AS [C1]
                FROM ( SELECT DISTINCT 
                    [Extent1].[Fio] AS [Fio], 
                    [Extent2].[Number] AS [Number]
                    FROM  [dbo].[People] AS [Extent1]
                    INNER JOIN [dbo].[Passports] AS [Extent2] ON [Extent1].[Passport_Id] = [Extent2].[Id]
                    WHERE [Extent1].[Room_Id] IS NOT NULL
                )  AS [Distinct1]
            )  AS [Project3]
        )  AS [Project4]

这是非常复杂的查询...但是,如果我将 l.FirstOrDefault().Name 替换为 Name = "",我会得到简单的查询

var qry = from peron in db.Persons
    join room in db.Rooms on peron.Room.Id equals room.Id
    join passport in db.Passports on peron.Passport.Id equals passport.Id
    select new {peron.Fio, room.Name, passport.Number, Count = 0};
qry = qry.GroupBy(l => new {l.Fio, l.Number}).Select(l => new {l.Key.Fio, Name = "", l.Key.Number, Count = l.Count()});    

SELECT 
        1 AS [C1], 
        [GroupBy1].[K1] AS [Fio], 
        N'' AS [C2], 
        [GroupBy1].[K2] AS [Number], 
        [GroupBy1].[A1] AS [C3]
        FROM ( SELECT 
            [Extent1].[Fio] AS [K1], 
            [Extent2].[Number] AS [K2], 
            COUNT(1) AS [A1]
            FROM  [dbo].[People] AS [Extent1]
            INNER JOIN [dbo].[Passports] AS [Extent2] ON [Extent1].[Passport_Id] = [Extent2].[Id]
            WHERE [Extent1].[Room_Id] IS NOT NULL
            GROUP BY [Extent1].[Fio], [Extent2].[Number]
        )  AS [GroupBy1]

如果我将 room.Name 添加到分组字段并以这种方式使用,我也会得到简单的查询

var qry = from peron in db.Persons
                    join room in db.Rooms on peron.Room.Id equals room.Id
                    join passport in db.Passports on peron.Passport.Id equals passport.Id
                    select new {peron.Fio, room.Name, passport.Number, Count = 0};
                qry = qry.GroupBy(l => new {l.Fio, l.Name, l.Number})
                      .Select(l => new 
                      {
                          l.Key.Fio, 
                          l.Key.Name, 
                          l.Key.Number, 
                          Count = l.Count()
                      });

如何解决 l.FirstOrDefault().Name 的问题? 谢谢。

最佳答案

由于您没有对组进行排序,我假设您只需要组中的任何名称。您可以使用像 Max 这样的聚合比(是的,它甚至适用于字符串)。我相信这会产生更合理的查询。

new {
       l.Key.Fio, 
       Name = l.Max(x => x.Name), 
       l.Key.Number, 
       Count = l.Count()
    });

关于c# - EF LINQ 翻译 : complex query,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33903037/

相关文章:

c# - 在不使用扩展方法的情况下使用通用逻辑扩展 C# 接口(interface)

c# - 如何运行只有 NotifyIcon 的 "empty"Windows 应用程序?

c# - EF映射表错误 "Invalid column name XXX_Id"

asp.net - ASP.NET 中的数据访问 : In-memory collection vs database

c# - LINQ 连接如何只选择第一条记录?

c# - 在 json 反序列化期间确定类型

c# - 使用 LINQ to Entities 向表中插入多条记录的正确方法

c# - 在 LINQ to Entities 中删除记录的正确方法

C# - 从 SQL 到 Linq - 左外连接/内连接

c# - ViewStart 和 Layout - 有什么区别?