计算2表的条件-Linq

问题描述

我有2张桌子,

产品表

id  produk  batch   qty
1   AAA    ADADAD   2
2   BBB    ADADAD   2
3   BBB    AAAAAA   2
...............

并移动表格

id  produk  batch   qty
1   BBB     ADADAD  1

我想从stok表中的数量减去移动表中的数量显示表,我想要的表

PRODUK  BATCH   QTY
AAA     ADADAD  2
BBB     ADADAD  1
BBB     AAAAAA  2

这是我的查询

var obj = _db.produk
       .Groupby(a=> new {a.code,a.batch})
       .Select(a=> new {
          produk = a.key.code,batch = a.Key.batch,qty = _db.move.Where(c => a.Any(p => p.code == a.code && p.batch == a.batch)).Sum(a=>a.qty)
       }).tolist();

但不起作用

解决方法

您必须进行LEFT JOIN才能分组移动表。

var moves =
  from m in _db.move
  group m by { m.code,m.batch } into g
  select
  {
      g.Key.code,g.Key.batch,qty = g.Sum(x => x.qty)
  };

var query = 
   from p in _db.produk
   join m in moves on new { p.code,p.batch } equals { m.code,m.batch } into j
   from m in j.DefaultIfEmpty()
   select new
   {
       produk = p.code,batch = p.batch.
       qty = p.qty - (int?)m.qty ?? 0
   };
,

如果您希望使用方法语法而不是查询语法,则可以这样编写查询:

var availableItems = repository
    .GroupJoin(purchases,stock => new { stock.Product,stock.Batch },move => new { move.Product,move.Batch },(stock,moves) => new { Stock = stock,Moves = moves })
    .SelectMany(
        stockAndRelatedMoves => stockAndRelatedMoves.Moves.DefaultIfEmpty(),(stockAndRelatedMoves,relatedMove) => new
        {
            stockAndRelatedMoves.Stock.Product,stockAndRelatedMoves.Stock.Batch,Quantity = stockAndRelatedMoves.Stock.Quantity - (relatedMove?.Quantity ?? 0)
        })
    .ToList();

如您所见,您需要使用GroupBy来代替GroupJoin,而不是简单的Select来使用SelectMany来从联接记录中检索项目。

一些解释:

  • stock => new { stock.Product,stock.Batch }:此处使用匿名类型,因为联接中使用了多个字段
  • stockAndRelatedMoves => stockAndRelatedMoves.Moves.DefaultIfEmpty():由于左外部联接而需要使用
  • (relatedMove?.Quantity ?? 0)relatedMove可以是null,这就是我们将其替换为0的原因

在上面的代码中,我使用了以下集合:

var repository = new List<Stock>
{
    new Stock { Id = 1,Product = "AAA",Batch = "ADADAD",Quantity = 2 },new Stock { Id = 2,Product = "BBB",new Stock { Id = 3,Batch = "AAAAAA",};

var purchases = new List<Move>
{
    new Move { Id = 1,Quantity = 1 }
};
,

您还可以查询produck表,然后在Select语句中,根据前身的movebatch属性过滤produck表,然后计算qty

代码如下:

        List<Produk> produks = new List<Produk>()
        {
            new Produk(){ id = 1,produk= "AAA",batch="ADADAD",qty = 2},new Produk(){ id = 2,produk= "BBB",new Produk(){ id = 3,batch="AAAAAA",};

        List<Remove> removes = new List<Remove>()
        {
            new Remove(){ id=1,produk="BBB",qty=1}
        };

        var result = (from p in produks
                      select new Produk
                      {
                          id = p.id,produk = p.produk,batch = p.batch,qty = p.qty - removes.Where(c => c.produk == p.produk && c.batch == p.batch).Sum(c => c.qty)
                      }).ToList();

结果如下:

enter image description here