2017-07-19 18 views
2

各パートについて、倉庫内と注文ライン内で割り当てられた合計を要約したいと思います。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を取得します。

EDIT:私はすでに非正規化バージョンがExpression Tree Lambdaであり、コンパイルエラーが発生するため、Giladのnull伝播演算子を除外しました。これはLinqPadで動作しますが。

このデータを2つのテーブルから集計するにはどうすればよいですか?

+0

は、私はあなたが直面して賭ける*デフォルト* LinqPadで動作しますが、残念ながら、Visual Studioの中で、私は「CS8072 \t式ツリーラムダがNULLを含めることはできませんを取得DefaultIfEmpty' –

答えて

4

使用Nullの伝播?.オペレーター:あなたは、それの使用方法の説明を見ることができます

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 joinコメントとあなたが見て取得エラー後


DefaultIfEmpy下:Why can't I use the null propagation operator in lambda expressions? これが実際のシナリオである場合は、代わりに?:演算子を使用してください。

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

'の一部伝播するオペレータ "だから私はそれを排除した。 –

+0

@StephenTurner - 更新を参照 –

+1

@アンダーソンピメンテル - 修正ありがとう:)逃した –

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

助けてくれてありがとうございます。これはまた動作しますが、intのヌルの余分なチェックは不要です。 –

関連する問題