从两个连接表中取消总计时的空引用

时间:2017-07-19 10:53:49

标签: c# linq

对于每个部分,我想总结一下在仓库和订单行中按顺序分配的总数。

我在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的null传播运算符,因为未简化的版本是Expression Tree Lambda,我收到编译错误。虽然这可以在LinqPad中使用。

如何从两个表中汇总这些数据?

2 个答案:

答案 0 :(得分:4)

使用Null Propagation ?.运算符:

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)

答案 1 :(得分:1)

尝试代码

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