用于收集的枚举器,具有时间/更新意识

时间:2010-12-13 08:48:05

标签: c# linq database-design

我有一种情况,我希望能够访问历史信息,以便回顾性地生成指标或理解过去某些方面的情况,直到现在我一直在存储最新的内容(例如已经应用了所有更新的记录)但现在希望能够转回时间

在推出自己的解决方案之前:

  • 是否还存在其他内容?
  • 这是标准模式吗?
  • 我可能会遇到什么问题?

我不希望记录的消费者能够更改它们,因此任何“更新”都应该通过存储库进行编组,它将创建包含完整内容的新记录。

理想情况下,我想把它转移到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.
}

3 个答案:

答案 0 :(得分:1)

如果您希望此解决方案使用SQL后端,那么您应该考虑ADO.NET实体框架或Linq-SQL。

您的主要潜在问题是您的枚举器,因此您需要查看一些方法并检查Linq生成的SQL(LinqPad对此有用)并确保其有效。

答案 1 :(得分:0)

您可以在RDBMS中实现一些解决方案;一个是存储给定键值的所有历史值以及'valid-from'和'valid-to'日期的地方。 (这通常用于数据仓库解决方案)。这会使您的查询变得非常复杂,并且很难改进现有的解决方案。我使用的另一种方法是保存作为现有表的副本的历史表,以及一些额外的元数据列;通过强制执行所有更新程序,您可以将更改前记录写入历史记录表。核心表上的任何现有查询都很好,因为它们看到了当前值,但对于历史查询,您可以UNION核心和历史表(通过我的情况下的视图)来提供LINQ对象的源。

在SQL Server中,我对历史记录表使用单独的历史记录模式,以便您可以重复使用表名。

答案 2 :(得分:0)

我后来发现这个问题有一个名称,我想要的数据库类型是'Temporal Database'

谷歌搜索该术语已经显示了一些非常有用的链接,包括一本完整的(绝版)书籍 从这个类似的discuss.joelonsoftware问题引用。

引用的书籍在此处以免费PDF格式提供:"Developing Time-Oriented Database Applications in SQL"