Linq Group by and Order by
本文关键字:by Order and Linq Group | 更新日期: 2023-09-27 18:09:20
我有一个sql查询,我按Name
分组,然后按Date
排序。我还需要为每组选择一个具有最新日期的条目。我怎么做,在linq(使用lambda表达式)?
select Name,Date,Comment
from Feedback
Group by Name,Date,Comment
order by Date desc
我的linq var query= db.Feedback
.GroupBy(f => f.Name, (f, g) => new
{
Name = f,
Comment = g.Select(h => h.Comment),
Date= g.Select(h => h.Date)
})
.Select(f => new { f.Name, f.Date, f.Comment}).ToList();
如何按Date
desc对每组进行排序并取第一个条目?
编辑
我已经更新了我的查询到
var query= db.Feedback.GroupBy(f => new { f.Name, f.Comment })
.Select(a => a.AsEnumerable())
.Select(b => b.OrderByDescending(f => f.Date)
.Select(c=>new{c.Name,c.Date,c.Comment}));
…并且执行最后一次Select可以防止JsonSerializer出现引用循环错误。
My Data应该是这样的
名字:Name1日期:9月28日评论:评论文本
名字:Name2日期:8月15日评论:评论文本
…但是它看起来是这样的
名字:Name1日期:9月28日评论:评论文本
名字:Name2日期:8月15日评论:评论文本
名字:Name1日期:8月1日评论:评论文本
…这就是解决方案
var query= db.Feedback
.GroupBy(f => new { f.Name})
.Select(a => a.AsEnumerable())
.Select(b => b.OrderByDescending(f => f.Date)
.Select(c => new { c.Name, c.Date, c.Comment})
.FirstOrDefault());
你的查询应该是:
var query= from f in db.Feedback
group f by new {f.Name, f.Date, f.Comment} into g
orderby g.Key.Date descending
select new {g.Key.Name, g.Key.Date, g.Key.Comment};
也:
var query= from f in db.Feedback
group f by new {f.Name, f.Date, f.Comment} into g
orderby g.Key.Date descending
select g.Key;
如果需要第一个元素,使用FirstOrDefault
扩展方法:
var first= query.FirstOrDefault();
如果你想让每组的第一个元素按Date
排序,那么你也可以这样做:
var query= from f in db.Feedback
group f by new {f.Name, f.Date, f.Comment} into g
select g.OrderByDescending(e=>e.Date).FirstOrDefault();
如果您只想按名称分组,则执行以下操作:
var query= from f in db.Feedback
group f by f.Name into g
select g.OrderByDescending(e=>e.Date).FirstOrDefault();
不能在Date列上应用GroupBy
和OrderBy
。因为如果您在GroupBy
中拥有它,它将在每个组中只给您一个Date值。所以如果你想按日期排序,你应该把它从group by中删除,然后使用这个:
var q = db.Feedback
.GroupBy(f => new {f.Name, f.Comment})
.Select( a => a.AsEnumerable())
.Select(b=> b.OrderByDescending(f => f.Date))
;
foreach (var item in q)
{
Debug.Log(item.FirstOrDefault().ToString());
}