实体框架的快照历史记录

Rai*_*oad 15 c# versioning audit entity-framework

我一直在寻找一些使用Entity Framework的审​​计钩子.其中许多都显示旧的/新的价值比较.这对于审计跟踪非常有用,但我正在寻找快照对象.

例如......假设我有一个管理产品的应用程序.产品具有多个属性和关联的其他对象.假设我将对象更改了10次.我们还要说,重要的是我可以查看这些对象更改的屏幕(不是审计跟踪,而是以只读格式实际显示的屏幕).我感兴趣的是能够为所有这10个更改(取决于我想看到的)检索原始EF产品对象(包含所有相关数据)并使用它来绑定到我的屏幕.

如果我正在使用SQL Server,那么我现在应该为序列化对象使用什么类型(XML,blob等)?这样做有意义吗?

Cra*_*ntz 11

让我们来看看.您需要获取对象图并将其序列化为数据库,格式允许您稍后实现它.我认为有一些工具可以做到这一点.其中之一就是实体框架.

你想做的是一件非常普遍的事情.考虑一个维基引擎.维基需要有一个每个人都看到的提示修订版,以及每个文档的后修订版.维基也需要能够以与显示提示修订版相同的方式显示修订版本.因此,应该为它们使用相同的存储格式.

我建议您允许对所有实体类型进行版本控制.编辑实体类型时,您将编辑提示修订并存储包含先前值的后修订.(您编辑提示修订而不是插入新提示的原因是因为其他对象(当前未实现为ObjectContext)可能包含指向您希望保留为提示链接的提示的链接,而不是链接到后面的版本.)

如有必要,可以对SQL Server表进行分区,以便将后端修订存储在不同的文件组中.这将允许您单独备份提示修订和备份修订.


Evk*_*Evk 5

首先,您需要向表中添加一组属性:

  • 版本 - 上次修改的时间(也可以是自动递增计数器而不是时间)。
  • LastModifiedBy - 对上次修改的用户的引用(如果你存储了它)。

然后,您有几个关于如何存储版本历史记录的选项。你可以

  1. 为要为其存储历史记录的每个主表创建一个新表。该历史表将具有与主表相同的所有字段,但不会强制执行主键和外键。对于每个外键,还存储在创建版本时引用条目的版本。

  2. 或者,您可以序列化与您的实体相关的所有有趣内容,并将您想要版本化的所有实体的所有序列化 blob 存储在一个全局历史表中(我个人更喜欢第一种方法)。

你如何填写你的历史表格?通过更新和删除触发器。

  • 在您的实体的更新触发器中 - 将所有以前的值复制到历史记录表中。对于每个外键 - 还复制引用实体的当前版本。
  • 在删除触发器中 - 基本上做同样的事情。

请注意,越来越多的现代系统并没有真正删除任何内容。他们只是内容标记为已删除。如果您想遵循此模式(这有几个好处) - 而不是删除添加 IsDeleted 标志到您的实体(当然,您必须在任何地方过滤已删除的实体)。

你如何看待你的历史?只需使用历史表,因为它具有与主表相同的所有属性 - 应该不是问题。但是 - 在扩展外键时 - 确保引用的实体版本与您存储在历史记录表中的相同。如果不是 - 您需要转到该引用实体的历史记录表并在那里获取值。通过这种方式,您将始终拥有那个时刻实体外观的快照,包括所有引用。

除了以上所有 - 您还可以将实体的状态恢复到任何以前的版本。

请注意,此实现虽然简单,但会消耗一些空间,因为它存储快照,而不仅仅是所做的更改。如果您只想存储更改 - 在更新触发器中,您可以检测哪些字段已更改,将它们序列化并存储在全局历史表中。这样,您至少可以在用户界面中显示已更改的内容和更改者(尽管您可能无法恢复到以前的某个版本)。