2010-09-10 71 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; 
     } 
    } 
}