2017-07-19 4 views
2

Für jedes Teil möchte ich die Summe im Lager und in der Reihenfolge in Auftragspositionen zusammenfassen.Nullreferenz beim Sumarisieren von Summen aus zwei verknüpften Tabellen

ich mit einer vereinfachten Version in LINQPad gerade arbeitete:

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

Aber das wird eine Nullreferenceexception, weil nicht alle Teile sowohl Lagerbestand und Bestellungen haben.

EDIT: Ich hatte bereits ausgeschlossen, Gilad Null propagieren, weil die nicht vereinfachte Version ist ein Ausdruck Tree Lambda und ich bekomme einen Kompilierungsfehler. Obwohl dies in LinqPad funktionieren würde.

Wie fasse ich diese Daten aus zwei Tabellen zusammen?

+0

Ich wette, Sie * konfrontiert Standard * Teil von 'DefaultIfEmpty' –

Antwort

4

Verwenden Null Propagation ?. Betreiber:

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

Sie Erklärung der Nutzung der es in ein left join unter DefaultIfEmpy


Nach Ihrem Kommentar sehen und den Fehler haben Sie bekommen einen Blick auf : Why can't I use the null propagation operator in lambda expressions? Wenn das wirklich Ihr Szenario ist, verwenden Sie stattdessen den Operator ?::

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

Das in LinqPad funktioniert, aber leider habe ich in Visual Studio bekommen„CS8072 \t Ein Ausdruck Baum Lambda kein Null enthalten propagierender Betreiber. " also hatte ich das ausgeschlossen. –

+0

@StephenTurner - siehe Update –

+1

@anderson Pimentel - danke für die Lösung :) verpasst, dass –

1

try Code

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

Danke, das funktioniert auch, obwohl die zusätzliche Überprüfung auf Nullen auf der Ints war unnötig. –

Verwandte Themen