2010-09-10 54 views
0

我有一个审计表,它存储SQL Server中单个任务级别的长期运行进程的审计行。LINQ按日期查找不重叠的审计记录

  • auditId INT,
  • TASKNAME为nvarchar(255),
  • 开始时间的日期时间,
  • 结束时间(日期时间,空),
  • 状态(为nvarchar(255),NULL)

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

例如

auditId,TASKNAME,开始时间,结束时间,状态

  1. Parent1,九时30分00秒,9时40分○○秒,有效
  2. Child1,9时30分01秒,九点35分00秒,有效
  3. CHILD2,9时35分01秒,九时40分00秒,有效
  4. Parent2,9时40分01秒,NULL,NULL
  5. Child3,九点40分02秒,NULL,NULL

通过ObservableCollection使用C#4.0/LINQ to Entities/LINQ我希望从过去X天获得该表的审计摘要,其中包含按状态显示的每一天的总持续时间。如果我能弄清楚如何获取摘要审计记录,那么我可以透视个别记录以生成摘要。

在审计工作的总结,应该:

  1. 没有任何重叠的审计记录,否则会重复计算时间。
  2. 需要处理的事实是,可能存在仍在当前日期运行的任务并返回空值
  3. 需要处理上一个任务结束与下一个任务开始之间的延迟。可能是通过获取当前任务的开始和下一个任务的开始之间的持续时间而不是当前任务的结束。
  4. 处理空值的一天的最后一个任务,不会有下列开始时间,如果我用在点描述的下一个记录的开始时间3

因此,使用总结上面的例子记录是:

auditId,TASKNAME,开始时间,结束时间,状态

  1. Parent1,09:30:00,9时40分01秒,有效
  2. Parent2,09:40:01,null,null

任何想法?

感谢

回答

0

找到关于EF不少“有趣”的事情,日期,同时搞清楚如何做到这一点。

所以最后我:

  1. 扩展审计日志表到一个新的可空的DateTime StartDateTimeOfNext和私人_startDateTimeOfNext添加到缓存前值。一旦计算,我不想再次计算它
  2. 向相同的部分类添加实体上下文
  3. 扩展审计表类以添加下面的代码。
  4. 我用DateTime.Today为DefaultIfEmpty与SQL Server 2005不支持C#DateTime.MinValue和DateTime.MaxValue
  5. 它不是特别漂亮,但它的工作原理
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; 
     } 
    } 
}