实体框架:按顺序排列,然后按分组

本文关键字:然后 顺序 框架 实体 排列 | 更新日期: 2023-09-27 18:30:10

我使用的是实体框架代码优先,并且有以下POCO,它表示我的数据库中的一个表。

public class LogEntry
{
    public int Id {get; set;}
    public DateTimeOffset TimeStamp {get;set;}
    public string Message {get; set;}
    public string CorrelationId {get; set;}
}

CorrelationId不是唯一的。表中通常会有多条具有相同CorrelationId的记录,此字段用于跟踪哪些日志条目对应于哪些请求。

然后我有了另一个对象,它允许我按CorrelationId对这些日志条目进行分组。此对象不会映射回数据库中的任何表。

public class AuditTrail
{
    public string CorrelationId {get; set;}
    public DateTimeOffset FirstEvent {get; set;}
    public List<LogEntry> LogEntries {get; set;}
}

我希望能够填充AuditTrail对象的列表。问题是,我希望对它们进行排序,以便最新的审计跟踪记录位于顶部。我也在进行分页,所以我需要在分组之前进行排序,以便返回正确的记录。即,我不想先得到结果,然后再对它们进行排序。在返回数据之前需要进行排序。

我尝试了一些查询,结果是:

var audits = from a in context.LogEntries
                             group a by a.CorrelationId into grp
                             select grp.OrderByDescending(g => g.TimeStamp);

这给了我一个IQueryable<IOrderedEnumerable<LogEntry>>返回,我通过它进行迭代来构建我的AuditTrail对象。问题是记录只在组中进行排序。例如,我将返回昨天的AuditTrail,然后是一周前的AuditTail,然后是今天的AuditTrail,但在LogEntries列表中,所有这些条目都已排序。我想要的是AuditTrails根据TimeStamp列按降序返回,以便在UI上的表顶部显示新的AuditTrail。

我也尝试过这个查询(根据实体框架按组跳过):

var audits = context.LogEntries.GroupBy(i => i.CorrelationId)
                               .Select(g => g.FirstOrDefault())
                               .OrderBy(i => i.TimeStamp)
                               .ToList();

这只会在我希望每个Correlation Id都按Correlation Id.分组时返回它们的第一个LogEntry。

实体框架:按顺序排列,然后按分组

我想你要找的是这样的东西:

var audits = (from a in context.LogEntries
             group a by a.CorrelationId into grp
             let logentries = grp.OrderByDescending( g => g.TimeStamp)
             select   new AuditTrail
                      {
                          CorrelationId = grp.Key,
                          FirstEvent = logentries.First().TimeStamp,
                          LogEntries = logentries.ToList()
                      }).OrderByDescending( at => at.FirstEvent);
var audits = (from a in context.LogEntries
             group a by a.CorrelationId into grp
             select new AuditTrail
             {
               CorrelationId = grp.Key,
               FirstEvent = grp.OrderBy(g=>g.TimeStamp).First().TimeStamp,
               LogEntries = grp 
             }).OrderByDescending(a=>a.FirstEvent)