【问题标题】:Calculate 2 table where condition - Linq计算 2 表 where 条件 - Linq
【发布时间】:2020-11-06 08:13:24
【问题描述】:

我有 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 表中的 qty 减去 move 表中的 qty 之后显示表,我想要什么表

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();

但不工作

【问题讨论】:

  • 在配置文件表和移动表之间进行联合,除了移动表应该有一个否定的数量。然后你对联合的结果进行分组。
  • 另一种解决方案是对 produk 进行 groupby 查询,对 move 进行 groupby 查询,然后在前两个查询之间进行连接查询,以处理外部连接情况。第一个解决方案更简单。

标签: c# asp.net-mvc linq asp.net-core


【解决方案1】:

您必须对分组移动表执行 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
   };

【讨论】:

    【解决方案2】:

    如果您更喜欢方法语法而不是查询语法,那么您可以这样编写查询:

    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();
    

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

    一些解释:

    • stock => new { stock.Product, stock.Batch }:这里使用匿名类型,因为在join中使用了多个字段
    • 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", Batch = "ADADAD", Quantity = 2 },
        new Stock { Id = 3, Product = "BBB", Batch = "AAAAAA", Quantity = 2 },
    };
    
    var purchases = new List<Move>
    {
        new Move { Id = 1, Product = "BBB", Batch = "ADADAD", Quantity = 1 }
    };
    

    【讨论】:

      【解决方案3】:

      您也可以查询produck表,然后在Select语句中,根据产品的batchproduck属性过滤move表,然后计算qty

      代码如下:

              List<Produk> produks = new List<Produk>()
              {
                  new Produk(){ id = 1, produk= "AAA", batch="ADADAD", qty = 2},
                  new Produk(){ id = 2, produk= "BBB", batch="ADADAD", qty = 2},
                  new Produk(){ id = 3, produk= "BBB", batch="AAAAAA", qty = 2},
              };
      
              List<Remove> removes = new List<Remove>()
              {
                  new Remove(){ id=1, produk="BBB", batch="ADADAD", 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();
      

      结果如下:

      【讨论】:

      • 这似乎不是很有效。对于每个 produk 记录,您扫描整个 removes 集合。在 MSSQL 中,它可能会导致 嵌套循环 而不是 Merge Join
      猜你喜欢
      • 2013-06-25
      • 2012-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多