Linq group by 与返回计数
Posted
技术标签:
【中文标题】Linq group by 与返回计数【英文标题】:Linq group by with return count 【发布时间】: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 你是对的
【参考方案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 您的模型是字符串而不是整数。然后你需要在数据库中创建一个链接到你的模型的表以上是关于Linq group by 与返回计数的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 LINQ group by 子句返回唯一的员工行?
C# Linq to sql 实现 group by 统计多字段 返回多字段