【问题标题】:How to use SUM and GROUP BY function in LINQ如何在 LINQ 中使用 SUM 和 GROUP BY 函数
【发布时间】:2020-12-23 01:57:02
【问题描述】:

实际上,我在 LINQ 中遇到问题,请帮助我解决这个问题。让我分享我的问题。我有两张桌子。

表 1

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

在此表中,我们显示了位置名称列表。

表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

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

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

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

    }

【问题讨论】:

  • 你的代码有什么问题?
  • 我没有得到这个输出
  • Stock_ID 的什么值被传递给操作?
  • 表 2 StockId
  • {1, 2} - 哪一个?

标签: asp.net-mvc entity-framework linq c#-3.0


【解决方案1】:

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

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

那么 SUM 行变为:

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

从我读到的 StockMovement 有一个位置字段,但这是位置 ID。使用 EF,利用导航属性来处理实体之间的 FK 关系是有益的。通过这种方式,您可以轻松地查询这些关系并让 EF 计算出适当的 SQL。这可以导致从对象图中读取更简单的表达式,而不是类似 SQL 的连接。

例如,而不是这个:

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

...使用导航属性并处理表中假定的列命名..

public class StockMovement
{
    // ... columns...
    [ForeignKey("Location"), Column("Location")]
    public int LocationId { get; set; }
    public virtual Location Location { get; set; }
}

这假定 StockMovement 表中 LocationId 的列称为“Location”。使用[Column] 属性或自定义映射(请参阅EntityTypeConfiguration 以供参考),您可以将EF 配置为映射字段,以便您的类可以保持一致的命名方法,即使它们引用的表没有。同样可以在类中将“Location_Name”更改为“LocationName”。您甚至可以通过利用 .Map(x => x.MapKey("Location")) (EF6) 或 Shadow Properties 来取消 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 语法更容易理解,因此将其作为一个选项考虑。

【讨论】:

    猜你喜欢
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 2016-05-24
    相关资源
    最近更新 更多