4

我跟踪对对象所做的所有更改,以便用户可以查看回滚到数据库中任何项目的任何先前版本。

历史数据库表如下所示

Item     | ItemId | Field     | WhenChanged         | OldValue | NewValue
customer | 6      | LastName  | 2009-12-31 13:00:04 | Sanders  | Sanders-Smith
customer | 5      | FirstName | 2009-12-31 12:11:14 | Jym      | Jim

目前,每当用户填写表格时,我都会记录这些更改,因此我可以获得对象新旧状态的完整信息。

但是,现在我需要从code中获取这些历史数据记录。当使用LINQ-to-SQL时,它需要透明地工作,即开发人员不应该做任何额外的工作,即以下代码也应该导致写入历史表:

using (var db = Datasource.GetContext())
{
    var customers = from c in db.Customers
        where c.Status == "waiting"
        select c;
    foreach(var customer in customers)
    {
        customer.Status = "finished";
    }
}
db.SubmitChanges();

我可以想象我可以通过两种方式实现这一点:

  1. 覆盖 db.SubmitChanges()但问题是我如何访问正在等待更改的对象。
  2. 将我的日志记录方法附加到OnSubmitChanges事件,但我还没有找到解决方案

有没有人解决过这个问题或知道解决这个问题的好方法?

4

3 回答 3

2

我在审计变更方面做了一些类似的工作——这是第一步。我的解决方案通过使我的设计器上下文抽象然后从中派生真实上下文并覆盖 SubmitChanges 来工作。它与单独的审计上下文和可以获取对象并从中构造审计对象的帮助类结合使用。它依赖于属性来提供关于哪个类是特定对象的审计类的必要信息。

您可以在我的博客http://farm-fresh-code.blogspot.com上找到更多信息。太复杂了,这里就不重复了。

于 2009-12-16T13:27:56.827 回答
2

对于您的第一个问题,您可以访问等待更改的对象,db.GetChangeSet()并了解哪些字段已更改以及原始值是什么,您可以使用:

ITable table = db.GetTable(entity.GetType());
ModifiedMemberInfo[] modifiedMembers = table.GetModifiedMembers(entity);
object original = table.GetOriginalEntityState(entity);
于 2009-12-16T13:48:55.900 回答
1

由于 L2S 为您生成代码,并且您希望更改生成代码的行为,我看到了两种可能性:

  1. 您开始使用 T4 模板从 dbml 文件生成代码并更改模板以添加您的功能。此处描述了此方法
  2. 您可以通过自己编写部分类来将功能添加到生成的(部分)数据上下文类中。在您的部分类中,您可以实现创建/更新/删除方法(CreateCustomer、UpdateCustomer 和 DeleteCustomer),添加存储更改的功能。

我希望这些指示可以帮助你。

于 2009-12-16T13:45:59.620 回答