繁体   English   中英

LINQ多对多左联接分组

[英]LINQ many to many Left Join Grouping

我有很多表关系的船:

CUS_Phone :拥有自己的唯一ID,其父表中的cus ID以及名称标题日期等。CUS_Phone_JCT :拥有自己的唯一ID,CUS_Phone的ID和CUS_Phone的ID CUS_Phone :拥有自己的唯一id和电话号码

在这里,我有一个联接查询来检索所有客户名称和电话号码:

var q = from c in CUS_Contact
    join cp in CUS_Phone_JCT on c.Id equals cp.Contact_Id into cp2 
    from cp3 in cp2.DefaultIfEmpty()
    join p in CUS_Phone on cp3.Phone_Id equals p.Id into p2 
    from p3 in p2.DefaultIfEmpty()
    where c.Cus_Id == 9120
    select new
            {
                c.Id,
                c.Cus_Id, 
                c.Namefirst, 
                c.Namemiddle, 
                c.Namelast, 
                cp3.Phone.Phone, 
                c.Title, 
                c.Dept, 
                c.Des, c.Datecreate, 
                c.Dateupdate, 
                c.Usr_idcreate, 
                c.Usr_idupdate
            };

foreach(var v in q){
Console.WriteLine(v.Id + "-" + v.Namefirst + "-" + v.Phone);
}

我该如何制定查询以将每个客户的号码分组? 我想查看具有每个客户编号列表(IEnumerable List)的不同客户。 LINQPad spanishOrders查询中有一个类似的示例,但是它们将每个订单的订单详细信息分组。 我不确定如何使用我的架构执行此操作。 谢谢!


编辑:这是从第一个答案输出的sql ...

-- Region Parameters
DECLARE @p0 Int SET @p0 = 4
-- EndRegion
SELECT (
    SELECT [t8].[id]
    FROM (
        SELECT TOP (1) [t6].[id]
        FROM [CUS_Contact] AS [t6]
        LEFT OUTER JOIN [CUS_Phone_JCT] AS [t7] ON [t6].[id] = [t7].[Contact_Id]
        WHERE [t2].[id] = [t6].[id]
        ) AS [t8]
    ) AS [Id], (
    SELECT [t11].[Cus_Id]
    FROM (
        SELECT TOP (1) [t9].[Cus_Id]
        FROM [CUS_Contact] AS [t9]
        LEFT OUTER JOIN [CUS_Phone_JCT] AS [t10] ON [t9].[id] = [t10].[Contact_Id]
        WHERE [t2].[id] = [t9].[id]
        ) AS [t11]
    ) AS [Cus_Id], (
    SELECT [t14].[namefirst]
    FROM (
        SELECT TOP (1) [t12].[namefirst]
        FROM [CUS_Contact] AS [t12]
        LEFT OUTER JOIN [CUS_Phone_JCT] AS [t13] ON [t12].[id] = [t13].[Contact_Id]
        WHERE [t2].[id] = [t12].[id]
        ) AS [t14]
    ) AS [Namefirst], (
    SELECT [t17].[namemiddle]
    FROM (
        SELECT TOP (1) [t15].[namemiddle]
        FROM [CUS_Contact] AS [t15]
        LEFT OUTER JOIN [CUS_Phone_JCT] AS [t16] ON [t15].[id] = [t16].[Contact_Id]
        WHERE [t2].[id] = [t15].[id]
        ) AS [t17]
    ) AS [Namemiddle], (
    SELECT [t20].[namelast]
    FROM (
        SELECT TOP (1) [t18].[namelast]
        FROM [CUS_Contact] AS [t18]
        LEFT OUTER JOIN [CUS_Phone_JCT] AS [t19] ON [t18].[id] = [t19].[Contact_Id]
        WHERE [t2].[id] = [t18].[id]
        ) AS [t20]
    ) AS [Namelast], (
    SELECT [t23].[title]
    FROM (
        SELECT TOP (1) [t21].[title]
        FROM [CUS_Contact] AS [t21]
        LEFT OUTER JOIN [CUS_Phone_JCT] AS [t22] ON [t21].[id] = [t22].[Contact_Id]
        WHERE [t2].[id] = [t21].[id]
        ) AS [t23]
    ) AS [Title], (
    SELECT [t26].[dept]
    FROM (
        SELECT TOP (1) [t24].[dept]
        FROM [CUS_Contact] AS [t24]
        LEFT OUTER JOIN [CUS_Phone_JCT] AS [t25] ON [t24].[id] = [t25].[Contact_Id]
        WHERE [t2].[id] = [t24].[id]
        ) AS [t26]
    ) AS [Dept], (
    SELECT [t29].[des]
    FROM (
        SELECT TOP (1) [t27].[des]
        FROM [CUS_Contact] AS [t27]
        LEFT OUTER JOIN [CUS_Phone_JCT] AS [t28] ON [t27].[id] = [t28].[Contact_Id]
        WHERE [t2].[id] = [t27].[id]
        ) AS [t29]
    ) AS [Des], (
    SELECT [t32].[datecreate]
    FROM (
        SELECT TOP (1) [t30].[datecreate]
        FROM [CUS_Contact] AS [t30]
        LEFT OUTER JOIN [CUS_Phone_JCT] AS [t31] ON [t30].[id] = [t31].[Contact_Id]
        WHERE [t2].[id] = [t30].[id]
        ) AS [t32]
    ) AS [Datecreate], (
    SELECT [t35].[dateupdate]
    FROM (
        SELECT TOP (1) [t33].[dateupdate]
        FROM [CUS_Contact] AS [t33]
        LEFT OUTER JOIN [CUS_Phone_JCT] AS [t34] ON [t33].[id] = [t34].[Contact_Id]
        WHERE [t2].[id] = [t33].[id]
        ) AS [t35]
    ) AS [Dateupdate], (
    SELECT [t38].[usr_idcreate]
    FROM (
        SELECT TOP (1) [t36].[usr_idcreate]
        FROM [CUS_Contact] AS [t36]
        LEFT OUTER JOIN [CUS_Phone_JCT] AS [t37] ON [t36].[id] = [t37].[Contact_Id]
        WHERE [t2].[id] = [t36].[id]
        ) AS [t38]
    ) AS [Usr_idcreate], (
    SELECT [t41].[usr_idupdate]
    FROM (
        SELECT TOP (1) [t39].[usr_idupdate]
        FROM [CUS_Contact] AS [t39]
        LEFT OUTER JOIN [CUS_Phone_JCT] AS [t40] ON [t39].[id] = [t40].[Contact_Id]
        WHERE [t2].[id] = [t39].[id]
        ) AS [t41]
    ) AS [Usr_idupdate], [t2].[id] AS [id2]
FROM (
    SELECT [t0].[id]
    FROM [CUS_Contact] AS [t0]
    LEFT OUTER JOIN [CUS_Phone_JCT] AS [t1] ON [t0].[id] = [t1].[Contact_Id]
    GROUP BY [t0].[id]
    ) AS [t2]
WHERE ((
    SELECT [t5].[Cus_Id]
    FROM (
        SELECT TOP (1) [t3].[Cus_Id]
        FROM [CUS_Contact] AS [t3]
        LEFT OUTER JOIN [CUS_Phone_JCT] AS [t4] ON [t3].[id] = [t4].[Contact_Id]
        WHERE [t2].[id] = [t3].[id]
        ) AS [t5]
    )) = @p0
GO

-- Region Parameters
DECLARE @x1 Int SET @x1 = 9327
-- EndRegion
SELECT [t2].[phone] AS [value]
FROM [CUS_Contact] AS [t0]
LEFT OUTER JOIN [CUS_Phone_JCT] AS [t1] ON [t0].[id] = [t1].[Contact_Id]
LEFT OUTER JOIN [CUS_Phone] AS [t2] ON [t2].[id] = [t1].[Phone_Id]
WHERE @x1 = [t0].[id]
GO
-- Region Parameters
DECLARE @x1 Int SET @x1 = 9328
-- EndRegion
SELECT [t2].[phone] AS [value]
FROM [CUS_Contact] AS [t0]
LEFT OUTER JOIN [CUS_Phone_JCT] AS [t1] ON [t0].[id] = [t1].[Contact_Id]
LEFT OUTER JOIN [CUS_Phone] AS [t2] ON [t2].[id] = [t1].[Phone_Id]
WHERE @x1 = [t0].[id]

我有点被你使用的困惑cp3.Phone.Phone除了你的joinCUS_Phone ,所以我要去承担前者意味着你不需要后者。 否则,只需切换p3cp3join和调整g.Select()相应。

也就是说,您应该能够简单地对联系人ID进行分组:

var q = from c in CUS_Contact
        join cp in CUS_Phone_JCT on c.Id equals cp.Contact_Id into cp2 
        from cp3 in cp2.DefaultIfEmpty()
        group new { c, cp3.Phone.Phone } by c.Id into g
        let c = g.First().c
        select new {
                       c.Id,
                       c.Cus_Id, 
                       c.Namefirst, 
                       c.Namemiddle, 
                       c.Namelast, 
                       Phones = g.Select(x => x.Phone)
                       c.Title, 
                       c.Dept, 
                       c.Des, c.Datecreate, 
                       c.Dateupdate, 
                       c.Usr_idcreate, 
                       c.Usr_idupdate
                   };

foreach(var v in q) {
    Console.WriteLine(v.Id + "-" + v.Namefirst);
    foreach(var p in v.Phones) {
        Console.WriteLine(" -" + p);
    }
}

在黑暗中拍摄一些照片以提高性能:

var q = from c in CUS_Contact
        join cp in CUS_Phone_JCT on c.Id equals cp.Contact_Id into cp2 
        from cp3 in cp2.DefaultIfEmpty()
        group new { c, cp3.Phone.Phone } by c.Id into g
        let c = g.First().c
        select new {
                       c.Id,
                       c.Cus_Id, 
                       c.Namefirst, 
                       c.Namemiddle, 
                       c.Namelast, 
                       Phones = g.Select(x => x.Phone)
                       c.Title, 
                       c.Dept, 
                       c.Des, c.Datecreate, 
                       c.Dateupdate, 
                       c.Usr_idcreate, 
                       c.Usr_idupdate
                   };

您也可以尝试使用组合键(包含所有c字段)而不是c.Id进行分组:

        group cp3.Phone.Phone
          by new { c.Id, c.Cus_Id, c.Namefirst, ETC } into g
        let c = g.Key
        select new {
                       ...
                       Phones = g.Select(p => p),
                       ...
                   }

更新:调整了组合键示例以仅将Phone值分组,因为您需要的所有其他内容都应在键中。


更新2:您可以通过嵌入子查询来简化很多事情:

var q = from c in CUS_Contact
        select new {
                       c.Id,
                       c.Cus_Id, 
                       c.Namefirst, 
                       c.Namemiddle, 
                       c.Namelast, 
                       Phones = (from cp in CUS_Phone_JCT
                                 where c.Id == cp.Contact_Id
                                 select cp.Phone.Phone),
                       c.Title, 
                       c.Dept, 
                       c.Des, c.Datecreate, 
                       c.Dateupdate, 
                       c.Usr_idcreate, 
                       c.Usr_idupdate
                   };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM