如何在 LINQ 中使用 SUM 和 GROUP BY 函数

How to use SUM and GROUP BY function in LINQ

实际上,我在 LINQ 中遇到了问题,请帮我解决这个问题。让我分享我的问题。我有 2 tables 和我在一起。

表 1

LocationID      LoginID     LocationName
  1               101           A
  2               101           B
  3               101           C

在此 table 中,我们显示的是位置名称列表。

表 2

ID      LoginID     STOCKID     QUANTITY        LocationID
1         101           1           10              1
2         101           1           -8              1   
3         101           2           20              2   
4         101           2           -5              2   
5         101           1           30              1

在此table中,我们显示了不同位置的库存商品数量列表。

现在,我想要的结果是分别显示每个位置的库存商品总量。 结果应该是这样的:

LocationID      LocationName        QUANTITY
  1                 A                   32
  2                 B                   15

让我与您分享我的代码。

 public ActionResult GetStockQuantityPartial(int? Stock_ID)
    {
        string loginId = Convert.ToString(Session["LoginId"]);

        var emp = (from m in context.StockMovements
                   join o in context.Locations
                   on m.Location equals o.LocationID
                   where m.Stock_ID == Stock_ID && m.LoginID == loginId
                   group new { m, o } by new { m.Location, m.Quantity, o.Location_Name } into grp
                   select new DisplayQuantityViewModel
                   {
                       Location = grp.Key.Location,
                       LocationName = grp.Key.Location_Name,
                       TotalStockQuantity = grp.Sum(x => x.m.Quantity)
                   }).ToList();


        return PartialView("_DisplayStockQuantity", emp);

    }

看起来问题是您在位置和数量上分组,而您只想在位置字段上对移动进行分组。

group m by new { o.LocationId, o.Location_Name } into grp

然后 SUM 行变为:

TotalStockQuantity = grp.Sum(x => x.Quantity)

据我了解,StockMovement 有一个 Location 字段,但这是 Location ID。借助 EF,将导航属性用于实体之间的 FK 关系是有益的。这样您就可以轻松地跨这些关系进行查询,并让 EF 计算出合适的 SQL。这可以导致更简单的表达式从对象图中读取而不是 SQL-like 连接。

例如,而不是这个:

public class StockMovement
{
    // ... columns...
    public int Location { get; set;}
}

...使用导航属性并解决 table..

中假定的列命名
public class StockMovement
{
    // ... columns...
    [ForeignKey("Location"), Column("Location")]
    public int LocationId { get; set; }
    public virtual Location Location { get; set; }
}

这假定 StockMovement table 中 LocationId 的列称为“位置”。使用 [Column] 属性或自定义映射(请参阅 EntityTypeConfiguration 以供参考)您可以配置 EF 以映射字段,这样您的 classes 可以保持一致的命名方法,即使 table他们没有提到。同样可以将 Location_Name 中的“Location_Name”更改为“LocationName”。您甚至可以通过利用 .Map(x => x.MapKey("Location")) (EF6) 或影子属性来取消 FK 列 (LocationId)。 (EF 核心)

利用导航 属性 可以将表达式简化为:

var emp = context.StockMovements
    .Where(x => x.Stock_ID == stockID && x.LoginID == loginId)
    .GroupBy(x => new { x.Location.LocationId, x.Location.LocationName })
    .Select(g => new DisplayQuantityViewModel
    {
        Location = g.Key.LocationId,
        LocationName = g.Key.LocationName,
        TotalStockQuantity = g.Sum(x => x.Quantity)        
    }).ToList();

从对象图/C# 的角度来看,我发现这比 Linq 语法更容易理解,所以把它扔在那里作为一个可供考虑的选项。