Linq按组和排序

6

我有一个 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降序排序并获取第一个条目? 编辑 我已更新我的查询为
    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}));

...并且执行最后一次选择可以防止JsonSerializer出现引用循环错误。

我的数据应该长成这样:

姓名: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());

你想要每个组的第一个元素吗? - CSharpie
是的,按最新日期排序。 - agri
2个回答

6
您的查询应为:
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();

我想获取按名称分组的最新日期/评论项。FirstOrDefault()将为整个查询提供第一项。 - agri
@agri,现在请检查我的答案。 - ocuenca
由于实际数据库引用了其他表,我得到了“检测到自引用循环”的错误。如何打破这个循环? - agri
有几种方法可以做到这一点,在这里你会找到很多。一个简单的方法是在你的上下文中禁用延迟加载和代理创建。 - ocuenca

3

在日期列上,您不能同时应用GroupByOrderBy。因为如果您在GroupBy中使用它,它将为每个组仅提供一个日期值。因此,如果您想按日期排序,则应将其从分组中删除并使用以下方法:

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

由于数据库中的日期类型为datetime,它给了我一个"DbSortClause表达式必须具有可排序的类型"错误。 - agri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接