Linq2第二列中有多列的左外联接

本文关键字:二列 Linq2 | 更新日期: 2023-09-27 18:22:19

我已经在谷歌上搜索并尝试了很多在这里找到的样本,但我无法让它工作。

我有以下SQL代码

Declare @PO as table
(Id int,
 Date datetime,
 PoNumber nvarchar(10),
 CustomerName nvarchar(100))
 Insert Into @PO values (1, '2013-07-15', 'po-01', 'Customer AAA')
Insert Into @PO values (1, '2013-07-15', 'po-02', 'Customer BBB')
Insert Into @PO values (1, '2013-07-15', 'po-03','Customer CCC')
Declare @SH as table
(Id int,
Date datetime,
PoNumber nvarchar(10),
ShNumber nvarchar(10),
DocumentType int)
Insert into @SH  values (1, '2013-07-20', 'po-01', 'sh-01', 1)
Insert into @SH  values (2, '2013-07-20', 'po-03', 'sh-02', 1)

Declare @SD as table
(Id int,
 Qty int,
 DocumentType int,
 ShNumber nvarchar(10),
 ShippingDate datetime)

Insert Into @SD values (1,1,1,'sh-01', '2013-08-01')
Insert Into @SD values (2,2,2,'sh-01', '2013-08-02')
Insert Into @SD values (3,1,1,'sh-01', '2013-08-03')
Insert Into @SD values (4,2,2,'sh-01', '2013-08-04')
Insert Into @SD values (5,1,1,'sh-01', '2013-08-05')
Insert Into @SD values (6,3,1,'sh-02', '2013-08-06')
Insert Into @SD values (7,1,1,'sh-02', '2013-08-07')
Insert Into @SD values (8,2,2,'sh-02', '2013-08-08')
Insert Into @SD values (9,1,2,'sh-02', '2013-08-09')


Select PO.PoNumber, CustomerName, Isnull(SH.ShNumber,''), Max(ShippingDate) ShippingDate, Sum(Isnull(SD.Qty,0)) QuantitySold From @PO PO
left join @SH SH
on PO.PoNumber = SH.PoNumber
left join @SD SD on SH.ShNumber = SD.ShNumber and SH.DocumentType = SD.DocumentType
group by PO.PoNumber, CustomerName, SH.ShNumber
order by PO.PoNumber

其正确返回

po-01   Customer AAA    sh-01   2013-08-05 00:00:00.000 3
po-02   Customer BBB        NULL    0
po-03   Customer CCC    sh-02   2013-08-07 00:00:00.000 4

使用出色的LinqPad,我尝试做同样的事情。

我创建了3个类

public class PO
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public string PoNumber { get; set; }
    public string CustomerName { get; set; }
}
public class SH
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public string PoNumber { get; set; }
    public string ShNumber { get; set; }
    public int Documenttype { get; set; }
}
public class SD
{
    public int Id { get; set; }
    public int Qty { get; set; }
    public int DocumentType { get; set; }
    public string ShNumber { get; set; }
    public DateTime ShippingDate { get; set; }
}

然后创建了与我的sql添加相同的测试日期

var po = new List<PO>();
    var sh = new List<SH>();
    var sd = new List<SD>();
    po.Add(new PO() {Id=1,Date = new DateTime(2013,7,15), PoNumber = "po-01", CustomerName = "Customer AAA"});
    po.Add(new PO() {Id=2,Date = new DateTime(2013,7,15), PoNumber = "po-02", CustomerName = "Customer BBB"});
    po.Add(new PO() {Id=3,Date = new DateTime(2013,7,15), PoNumber = "po-03", CustomerName = "Customer CCC"});
    sh.Add(new SH() {Id=1, Date = new DateTime(2013,7,20), PoNumber = "po-01", ShNumber = "sh-01", Documenttype= 1});
    sh.Add(new SH() {Id=2, Date = new DateTime(2013,7,20), PoNumber = "po-03", ShNumber = "sh-02", Documenttype= 1});
    sd.Add(new SD() {Id=1, ShippingDate = new DateTime(2013,8,1), ShNumber = "sh-01", DocumentType = 1, Qty = 1});
    sd.Add(new SD() {Id=2, ShippingDate = new DateTime(2013,8,2), ShNumber = "sh-01", DocumentType = 2, Qty = 2});
    sd.Add(new SD() {Id=3, ShippingDate = new DateTime(2013,8,3), ShNumber = "sh-01", DocumentType = 1, Qty = 1});
    sd.Add(new SD() {Id=4, ShippingDate = new DateTime(2013,8,4), ShNumber = "sh-01", DocumentType = 2, Qty = 2});
    sd.Add(new SD() {Id=5, ShippingDate = new DateTime(2013,8,5), ShNumber = "sh-01", DocumentType = 1, Qty = 1});
    sd.Add(new SD() {Id=6, ShippingDate = new DateTime(2013,8,6), ShNumber = "sh-02", DocumentType = 1, Qty = 3});
    sd.Add(new SD() {Id=7, ShippingDate = new DateTime(2013,8,7), ShNumber = "sh-02", DocumentType = 1, Qty = 1});
    sd.Add(new SD() {Id=8, ShippingDate = new DateTime(2013,8,8), ShNumber = "sh-02", DocumentType = 2, Qty = 2});
    sd.Add(new SD() {Id=9, ShippingDate = new DateTime(2013,8,9), ShNumber = "sh-02", DocumentType = 2, Qty = 1});

然而,当我试图重现相同的逻辑来查询该数据时,我会丢失第二个左联接及其分组

这是我停止的地方

var query = from p in po
                join h in sh
                on p.PoNumber equals h.PoNumber into j2
                from j3 in j2.DefaultIfEmpty()
                group j3 by new {CustomerName = p.CustomerName, PoNumber = p.PoNumber, DocumentType = j3 == null ? 0 : j3.Documenttype, ShNumber = j3 == null ? string.Empty : j3.ShNumber}
                into grouped
                join d in sd
                on new {grouped.Key.ShNumber, grouped.Key.DocumentType} equals new {d.ShNumber, d.DocumentType} into k2
                from k3 in k2.DefaultIfEmpty()
                group new {k3.ShippingDate, k3.Qty} by new {grouped.Key.ShNumber, grouped.Key.CustomerName, grouped.Key.PoNumber} into g2
                select new {
                                PoNumber = g2.Key.PoNumber,
                                CustomerName = g2.Key.CustomerName,
                                ShNumber = g2.Key.ShNumber,
                                Qty = g2.Sum(o => o.Qty),
                                ShippingDate = g2.Max(o => o.ShippingDate)
                            };

如果有人能帮忙,我们将不胜感激。

Linq2第二列中有多列的左外联接

我想明白了在结束时执行求和和和最大值时,我必须检查零值

var query = from p in po
                join h in sh
                on p.PoNumber equals h.PoNumber into j2
                from j3 in j2.DefaultIfEmpty()
                group j3 by new {CustomerName = p.CustomerName, PoNumber = p.PoNumber, DocumentType = j3 == null ? 0 : j3.Documenttype, ShNumber = j3 == null ? string.Empty : j3.ShNumber}
                into grouped
                join d in sd
                on new {grouped.Key.ShNumber, grouped.Key.DocumentType} equals new {d.ShNumber, d.DocumentType} into k2
                from k3 in k2.DefaultIfEmpty()
                group k3 by new {ShNumber= grouped.Key.ShNumber, CustomerName = grouped.Key.CustomerName, PoNumber = grouped.Key.PoNumber} into g2
                select new {
                                PoNumber = g2.Key.PoNumber,
                                CustomerName = g2.Key.CustomerName,
                                ShNumber = g2.Key.ShNumber,
                                Qty = g2.Sum(o => o == null ? 0 : o.Qty),
                                ShippingDate = g2.Max(o => o == null ? DateTime.MinValue : o.ShippingDate)
                            };