【问题标题】:Linq group by with return countLinq group by 与返回计数
【发布时间】:2020-11-03 22:14:48
【问题描述】:

Net 核心和 Linq。我有如下表

订单表

OrderId   Status
1         New
2         New
3         In Progress
4         In Progress
5         Closed
6         Closed

我有以下型号

public class SummaryEntity
 { 
  public int New { get; set; }
  public int InProgress { get; set; }
  public int Closed { get; set; }
 }

然后我需要返回并绑定到下面的模型,如下所示

New : 2
InProgress : 2
Closed : 2 

我尝试过类似下面的方法

SummaryEntity result = (from item in Orders
                          group item by new { item.Status } into g
                          select new SummaryEntity{ //not sure how to get count and assign it to model }
                           );

我发现很难对模型进行分组和赋值。有人可以帮我写查询。任何帮助,将不胜感激。谢谢

【问题讨论】:

  • SummaryEntity 是单类,您想如何将其转换为列表?看来,计算 3 次会更好
  • 嗨对不起我的错误,已删除 toList()
  • Orders.Count(o => o.Status == "New") 和其他状态相同。另外,为什么 count 是string
  • 嗨,帕维尔,哪个算?我找不到它
  • 是的 pavel 我改成 int 你是对的

标签: c# linq group-by


【解决方案1】:

您已经按状态对项目进行了分组,因此g.Key 将包含状态值,g 本身就是分组项目的可枚举。如果你想计算他们的数量,请使用Count(),例如:

var counts = from item in Orders
             group item by new { item.Status } into g
             select new {status=g.Key, count=g.Count()};

这将为每个状态值返回一个对象及其计数。为每个状态获取不同的列本质上是旋转,将行转换为列。

但在这种情况下,如果您事先知道状态名称,您可以将结果转换为字典并按名称检索计数,例如:

var dict=counts.ToDictionary(x=>x.status,x=>x.count);

var model= new SummaryEntity 
           {
               New        = dict.TryGetValue("New",out var c_n)
                            ? c_n : 0,
               InProgress = dict.TryGetValue("InProgress",out var c_p)
                            ? c_p : 0,
               Closed     = dict.TryGetValue("Closed",out var c_c)
                            ? c_c : 0,
           };

Dictionary.TryGetValue 用于在缺少状态值时避免异常

【讨论】:

  • 非常好。您可以使用ToLookup 简化此操作,如var byStatus = Orders.ToLookup(o => o.Status);,然后您可以编写new SummaryEntity { New = byStatus["New"].Count(), ... }
  • @AluanHaddad 这不会简化查询,它会延迟计数计算。如果 OP 使用 EF,GroupBy 将只返回状态值和计数,而ToLookup 将返回所有项目并将计数计算留给.Count()
  • 我的意思是简化代码,因为您不需要检查密钥。你总是可以Orders.ToLookup(o => o.Status, o => o.OrderId);
【解决方案2】:

你的模型没有意义。您只有状态不是 New、InProgress、Closed。尝试以下:

            DataTable dt = new DataTable();
            dt.Columns.Add("OrderId", typeof(int));
            dt.Columns.Add("Status", typeof(string));
            
            dt.Rows.Add( new object[] { 1, "New"});
            dt.Rows.Add( new object[] { 2, "New"});
            dt.Rows.Add( new object[] { 3, "In Progress"});
            dt.Rows.Add( new object[] { 4, "In Progress"});
            dt.Rows.Add( new object[] { 5, "Closed"});
            dt.Rows.Add( new object[] { 6, "Closed"});

            var results = dt.AsEnumerable()
                .GroupBy(x => x.Field<string>("Status"))
                .Select(x => new { status = x.Key, count = x.Count() })
                .ToList();

【讨论】:

  • 嗨,感谢您的回答,但我需要将其分配给模型,例如,如果状态 New 为零,那么我想返回 New:0
  • 您的模型是字符串而不是整数。然后你需要在数据库中创建一个链接到你的模型的表
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 2012-08-29
相关资源
最近更新 更多