【问题标题】:Entity Framework: Order by and then group by实体框架:排序,然后分组
【发布时间】:2016-01-12 15:08:25
【问题描述】:

我首先使用实体​​框架代码,并有以下 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 对象的列表。问题是我希望对它们进行排序,以便最新的 Audit Trail 记录位于顶部。我也在进行分页,所以我需要在 group by 之前发生 order by,以便返回正确的记录。即我不想得到结果然后对它们进行排序。排序需要在数据返回之前进行。

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

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

这给了我一个IQueryable&lt;IOrderedEnumerable&lt;LogEntry&gt;&gt; 返回,我通过它迭代来构建我的 AuditTrail 对象。问题是记录仅在组内排序。例如,我将返回昨天的 AuditTrail,然后是一周前的一个,然后是今天的一个,但在 LogEntries 列表中,所有这些条目都已排序。我想要的是 AuditTrails 基于 TimeStamp 列以降序返回,以便新的 AuditTrails 显示在 UI 上我的表格顶部。

我也试过这个查询(根据Entity Framework skip take by group by):

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

当我希望它们全部按 Correlation Id 分组时,这只会返回每个 Correlation Id 的第一个 LogEntry。

【问题讨论】:

    标签: c# entity-framework entity-framework-6


    【解决方案1】:

    我认为您正在寻找的是这样的:

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

    【讨论】:

    • 现在接受,因为数据看起来正确。明天将进行更严格的测试并在必要时更新。
    • 好的,如果您有任何问题,请告诉我;)
    【解决方案2】:
    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)
    

    【讨论】:

      猜你喜欢
      • 2011-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多