Linq 2左外连接第二个中有多个列

时间:2013-07-15 14:41:42

标签: c# linq

我用谷歌搜索并尝试了很多这里找到的样本,但我无法让它发挥作用。

我有以下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)
                            };

如果有人可以提供帮助,那将非常感激。

1 个答案:

答案 0 :(得分:2)

我想通了。我必须在结束时做Sum和Max时检查空值

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)
                            };