使用linq lambda表达式在同一表中求和

时间:2018-09-27 20:41:16

标签: linq

我是使用LINQ lambda表达式的新手,必须在名为stock的表中进行查询,并且该表具有属性(id,prodId,prodCode,Quantity,StockInternalStatus,位置),StockInternalStatus可用或不可用,我想要做的是获得一个列表,其中包含每种产品的总数量和总可用数量,这意味着,例如,如果我有以下库存:

Stock1: prodCode = A; Qty = 1; StockInternalStatus = Available; Location = sd1
Stock2: prodCode = A; Qty = 2; StockInternalStatus = Not Available; Location = sd2
Stock3: prodCode = B; Qty = 2; StockInternalStatus = Available; Location = sd3
Stock4: prodCode = B; Qty = 2; StockInternalStatus = Available; Location = sd4

结果应该是:

prodCode = A; TotalQuantity = 3; QtyAvailable = 1

prodCode = A; TotalQuantity = 4; QtyAvailable = 4

有人可以帮我吗?我已经打了3天的代码并进行测试,但是它不起作用。这是我编写的代码:

Context.Stocks.Where(e=>e.IsActive /*&& ( e.ProductCode=="63149")*/)
.GroupBy(s=>s.ProductCode)
.SelectMany(gr=>gr.Select(st=>new
{
             TotalQuantity = gr.Sum(c=>c.Quantity),

             Count = gr.Count(),
             Pr= st.ProductCode,
             PrId = st.ProductId,
             StockInternalStatus = st.StockInternalStatus   
}))
//.Distinct()
.GroupJoin
(Context.Stocks.Where(p=>p.StockInternalStatus=="Available" && p.IsActive)
, ss => ss.PrId, sss => sss.ProductId, 
(ss,sss) => new { TotalQuantity = ss.TotalQuantity, ProductCode = ss.Pr,
QtyAvailable = sss.Sum(a=>a.Quantity)
})
.Distinct()
.DefaultIfEmpty()

并且,如果我指定产品代码,它将为我提供该产品的结果,但是如果我想获得所有产品的结果,则会收到以下错误:

  

错误:强制转换为值类型'System.Decimal',因为实例化值为null。结果类型的通用参数   否则查询必须使用可为空的类型

根据我的理解,这个错误是,第一次协商产生的一些产品在与GroupJoin进行第二次协商时由于没有可用而无法发布,因为我只取出第二次可用的,有兴趣让我拿走所有可用的总金额,但我不确定我是否理解得很好。

谢谢您的帮助。

1 个答案:

答案 0 :(得分:0)

您可以使用projections从列表中选择和格式化多种数据(TotalQuantityQtyAvailable)。这是您的问题的有效示例:

var products = Context.Stocks.GroupBy(s => s.ProdCode)
                             .Select(s => new
                             {
                                 ProdCode = s.Key,
                                 TotalQuantity = s.Sum(o => o.Qty),
                                 QtyAvailable = s.Where(o => o.StockInternalStatus == "Available").Sum(o => o.Qty)
                             });