2013-07-15 105 views
2

我已經Google搜索並嘗試了很多在這裏找到的示例,但我無法使其工作。Linq 2左外部加入第二個中的多個列

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

如果有人可以幫忙,那將是非常感激。

回答

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