2010-12-13 17 views
2

我有一種情況,我希望能夠訪問歷史信息以便回顧性地生成度量標準或瞭解事物在過去的某個點上的方式,直到現在爲止一直在存儲最新的內容(例如,所有更新應用的記錄),但現在想要能夠將時鐘調回作爲時間/更新感知的集合的枚舉器

滾動我自己的解決方案之前:

  • 難道別的東西存在?
  • 這是一個標準模式?
  • 我在哪裏可能遇到問題?

我並不希望記錄的使用者能夠更改它們,因此應該通過存儲庫整理任何「更新」,它將創建包含完整內容的新記錄。

理想情況下,我想將其移至SQL後端,因此如果模式存在,我希望保持靠近它們。


基本設計思想是:

定義一個接口,說IUpdatableRecord:

public interface IUpdatableRecord<K> 
{ 
    K Key { get; } 
    DateTime Updated { get; } 
} 

定義與枚舉能力的存儲庫:

public class DataRepository : IEnumerable<IUpdateableRecord<K>> 
{ 
    // Some internal collection that allows duplicate keys 
    private IList<IUpdateableRecord<K>> dataStore = ....; 

    // Some enumerator overloads 
    public IEnumerator<IUpdateableRecord<K>> GetEnumerator() 
    { 
     return dataStore.GetEnumerator(); 
    } 

    // enumerator for contents as of a specific date-time 
    public IEnumerator<IUpdateableRecord<K>> GetEnumerator(DateTime refDate) 
    { 
     // Group by key (so all versions of a record together) 
     var groupedByKey = dataStore.GroupBy(r => r.Key); 

     // Sort the keys within each group for a date/time order 
     foreach (var rec in groupedByKey) 
     { 
      var sorted = rec.OrderBy(r => r.Updated); 

      // Ignore updates after the reference date & keep last (or default) 
      var last = sorted.Where(r => r.Updated < refDate).LastOrDefault(); 

      // yield last record if any 
      if (last != null) 
      { 
       yield return last; 
      } 
     } 
    } 

    // code for 'adding/updating' a record. 
} 
+0

誰做你打算設置更新時間?它是回購,還是用戶??看到你在界面上有一個只讀更新方法,所以假設它是回購。 – 2010-12-13 08:52:18

+0

我假設存儲庫或其他委託類將保持更新的時間 - 我認爲歷史數據的消費者不應該有能力更改內容,因此應該向其提供只讀記錄(但其餘部分問題是從這個問題中抽象出來的)。 – 2010-12-13 09:23:01

+0

如果文檔中顯示「截至」,我希望計算是'<= refDate'。 – Gabe 2010-12-14 09:10:07

回答

1

如果你想這個解決方案利用SQL後端,那麼你應該考慮ADO.NET實體框架或LINQ-SQL。

您的主要潛在問題是您的枚舉器,因此您需要查看多種方法並檢查由Linq生成的SQL(LinqPad對此很有用),並確保其效率。

0

有幾種解決方案可以在RDBMS中執行;一個是您存儲給定鍵值的所有歷史值以及「有效日期」和「有效日期」的位置。 (這通常用於數據倉庫解決方案)。這可能使您的查詢複雜化很多,並且很難將其改造爲現有的解決方案。我使用的另一種方法是保存現有表的副本歷史記錄表,以及一些額外的元數據列;通過強制所有程序更新,您可以將預先更改的記錄寫入歷史記錄表。核心表上任何現有的查詢都很好,因爲他們看到了當前值,但對於歷史查詢,您可以將核心表和歷史表聯合起來(通過我的案例中的視圖)來爲LINQ對象提供源。

在SQL Server中,我使用歷史表的單獨歷史記錄模式,因此您可以重新使用表名稱。