2017-07-19 35 views
2

對於每個部分,我想總結一下並在倉庫中分配的總數以及訂單中的順序。當從兩個連接的表中總結總數時爲空引用

我在LINQPad一個簡化版本的工作:

void Main() 
{ 
    var partQuantities = (
     from part in Parts() 

     join orderLine in OrderLines() 
      on part.PartID equals orderLine.PartID 
      into orderLineLeftJoin 
     from orderLine in orderLineLeftJoin.DefaultIfEmpty() 

     join warehouse in Warehouses() 
      on part.PartID equals warehouse.PartID 
      into warehouseLeftJoin 
     from warehouse in warehouseLeftJoin.DefaultIfEmpty() 

     group new { warehouse, orderLine } by part into partQtys 

/* 
     select partQtys 
// */ 

// /* 
     select new 
     { 
      partQtys.Key.PartID, 
      OnHandQty = partQtys.Sum(partQty => partQty.warehouse.OnHandQty), 
      AllocatedQty = partQtys.Sum(partQty => partQty.warehouse.AllocatedQty), 
      OrderQty = partQtys.Sum(partQty => partQty.orderLine.OrderQty) 
     } 
// */ 
     ).Dump(); 
} 

class Part { public string PartID; } 
private Part[] Parts() { return new Part[] {new Part { PartID = "PartA" },new Part { PartID = "PartB" },new Part { PartID = "PartC" },new Part { PartID = "PartD" },new Part { PartID = "PartE" },new Part { PartID = "PartF" }}; } 

class Warehouse { public string WarehouseID; public string PartID; public int OnHandQty; public int AllocatedQty; } 
private Warehouse[] Warehouses() { return new Warehouse[] {new Warehouse { WarehouseID = "Whse1", PartID = "PartA", OnHandQty =101, AllocatedQty = 21 },new Warehouse { WarehouseID = "Whse1", PartID = "PartB", OnHandQty =102, AllocatedQty = 22 },new Warehouse { WarehouseID = "Whse1", PartID = "PartC", OnHandQty =103, AllocatedQty = 23 },new Warehouse { WarehouseID = "Whse1", PartID = "PartD", OnHandQty =104, AllocatedQty = 24 },new Warehouse { WarehouseID = "Whse2", PartID = "PartC", OnHandQty =105, AllocatedQty = 25 },new Warehouse { WarehouseID = "Whse2", PartID = "PartD", OnHandQty =106, AllocatedQty = 26 },new Warehouse { WarehouseID = "Whse2", PartID = "PartE", OnHandQty =107, AllocatedQty = 27 },new Warehouse { WarehouseID = "Whse2", PartID = "PartF", OnHandQty =108, AllocatedQty = 28 }}; } 

class OrderLine { public string OrderID; public string PartID; public int OrderQty; } 
private OrderLine[] OrderLines() { return new OrderLine[] {new OrderLine { OrderID = "Order1", PartID = "PartB", OrderQty = 71 }, new OrderLine { OrderID = "Order1", PartID = "PartF", OrderQty = 72 },new OrderLine { OrderID = "Order2", PartID = "PartD", OrderQty = 73 }, new OrderLine { OrderID = "Order2", PartID = "PartF", OrderQty = 74 }}; } 

但是,這得到一個NullReferenceException,因爲不是所有的部件都具有倉庫庫存和訂單。

編輯:我已經排除了Gilad的空傳播操作符,因爲unsimplified版本是一個表達式樹lambda和我得到一個編譯錯誤。雖然這可以在LinqPad中使用。

如何從兩張表中總結這些數據?

+0

我敢打賭,你面對*默認* DefaultIfEmpty' –

回答

4

使用空傳播?.操作:

select new 
{ 
    partQtys.Key.PartID, 
    OnHandQty = partQtys.Sum(partQty => partQty.warehouse?.OnHandQty), 
    AllocatedQty = partQtys.Sum(partQty => partQty.warehouse?.AllocatedQty), 
    OrderQty = partQtys.Sum(partQty => partQty.orderLine?.OrderQty) 
} 

你可以看到它的使用說明在left joinDefaultIfEmpy


追隨你的評論,你會得到看看錯誤:Why can't I use the null propagation operator in lambda expressions? 如果那真的是你的場景,那就用?:運營商:

OnHandQty = partQtys.Sum(p => p.warehouse == null ? 0 : p.warehouse.OnHandQty) 
+0

在LinqPad工作,但不幸的是,在Visual Studio中,我得到的'一部分「CS8072 \t表達式樹lambda不能包含空傳播運營商「。所以我排除了這一點。 –

+0

@StephenTurner - 查看更新 –

+1

@安德森Pimentel - 感謝您的修復:)錯過了 –

1

try代碼

select new 
    { 
     partQtys.Key.PartID, 
     OnHandQty = partQtys.Where(c=>c.warehouse!=null).Sum(partQty => partQty.warehouse.OnHandQty), 
     AllocatedQty = partQtys.Where(c=>c.warehouse!=null).Sum(partQty => partQty.warehouse.AllocatedQty), 
     OrderQty = partQtys.Where(c=>c.orderLine!=null).Sum(partQty => partQty.orderLine.OrderQty) 
    } 
+0

謝謝,這也適用,雖然額外檢查整數在整數是不必要的。 –