LINQ按日期查找不重叠的审计记录

时间:2010-09-10 09:20:35

标签: linq linq-to-entities c#-4.0 linq-to-objects

我有一个审计表,用于存储SQL Server中单个任务级别的长时间运行进程的审计行。

  • auditId int,
  • TaskName nvarchar(255),
  • StartTime datetime,
  • EndTime(datetime,null),
  • 状态(nvarchar(255),null)

该过程包含父步骤和子步骤,每个步骤都记录到审计表中。任务可能会也可能不会拥有父级。

e.g。

auditId,TaskName,StartTime,EndTime,Status

  1. Parent1,09:30:00,09:40:00,有效
  2. Child1,09:30:01,09:35:00,有效
  3. Child2,09:35:01,09:40:00,有效期
  4. Parent2,09:40:01,null,null
  5. Child3,09:40:02,null,null
  6. 在ObservableCollection上使用C#4.0 / LINQ到实体/ LINQ我想从过去的X天获得该表的审计摘要,其中包含每个状态的总持续时间。如果我可以弄清楚如何获取摘要审核记录,我可以透视各个记录以生成摘要。

    在审核摘要中应该:

    1. 不会有任何重叠的审核记录,否则将重复计算持续时间。
    2. 需要处理这样一个事实,即当前日期仍然可以运行任务并返回null
    3. 需要处理上一个任务结束和下一个任务开始之间的延迟。可能通过获取当前任务的开始和下一个任务的开始之间的持续时间而不是当前任务的结束。
    4. 如果我使用第3点所述的下一条记录的开始时间,则处理当天最终任务的空值,该任务将没有以下开始时间
    5. 因此,使用上面的示例摘要记录将是:

      auditId,TaskName,StartTime,EndTime,Status

      1. Parent1,09:00:00, 09:40:01 ,有效
      2. Parent2,09:40:01,null,null
      3. 有什么想法吗?

        由于

1 个答案:

答案 0 :(得分:0)

在确定如何做到这一点时,发现了很多关于EF和日期的“有趣”事情。

所以最后我:

  1. 扩展审计日志表以添加新的可空DateTime StartDateTimeOfNext和private _startDateTimeOfNext以缓存先前的值。一旦计算出来,我就不想再计算了
  2. 向同一个分类
  3. 添加了实体上下文
  4. 扩展Audit表类以添加以下代码。
  5. 我使用DateTime.Today作为DefaultIfEmpty,因为SQL Server 2005不支持C#DateTime.MinValue和DateTime.MaxValue
  6. 它不是特别漂亮,但它有效
  7.   public DateTime? StartDateTimeOfNext
    {  
        get  
        {  
            if (_startDateTimeOfNext == null)  
            {  
                DateTime windowMin = this.StartTime.Date;
                DateTime windowMax = this.StartTime.Date.AddDays(1).AddMinutes(-1);
                DateTime? query = (from nextAuditLog in AuditLog.AuditLogEntityContext.AuditLogs
                where nextAuditLog.auditId > this.auditId 
                && nextAuditLog.StartTime > this.StartTime 
                && nextAuditLog.StartTime <= windowMax 
                && nextAuditLog.StartTime >= windowMin
                orderby nextAuditLog.auditId ascending
                select nextAuditLog.StartTime
                ).DefaultIfEmpty(DateTime.Today).First();               
                if (query != DateTime.Today)
                {
                    _startDateTimeOfNext = query;
                    return query;
                }
                else
                {
                    _startDateTimeOfNext = this.EndTime;
                    return this.EndTime;
                }
            }
            else
            {
            return _startDateTimeOfNext;
            }
        }
    }