保留 EF 实体特定属性的值历史记录
我需要保留 EF4 ASP.NET MVC3 应用程序中某些字段的值的历史记录。这只需要是一个日志文件,记录用户、日期时间、表名、字段名、旧值、新值。
虽然在各种保存例程中对此进行编码非常容易,但我想知道是否可以通过将其连接到某种数据注释中来获得全局覆盖,这样我也许可以
[KeepHistory()]
public string Surname { get; set; }
在我的部分类中声明(我正在使用 POCO 但从 T4 模板生成)。
所以问题
1) 这是一个坏主意吗?我基本上建议对实体进行副作用更改,而不是由代码直接引用,作为注释的结果。
2)可以做到吗?我是否可以访问与我的工作单元相关的正确上下文,以便通过上下文保存保存或删除更改?
3)有更好的方法吗?
4)如果您建议我这样做,任何指示都会受到赞赏 - 我读到的所有内容都是为了验证,这可能不是最好的起点。
I have a requirement to keep a history of values of some fields in an EF4 ASP.NET MVC3 application. This just needs to be a log file of sorts, log the user, datetime, tablename, fieldname, oldvalue, newvalue.
Although it would be pretty easy to code this in various save routines, I'm wondering if I can get global coverage by wiring it into some sort of dataannotation, so that I can perhaps declare
[KeepHistory()]
public string Surname { get; set; }
in my partial class (I'm using POCO but generated from a T4 template).
So Questions
1) Is this a bad idea ? I'm basically proposing to side-effect changes to an entity, not directly referenced by the code, as a result of an annotation.
2) Can it be done ? Will I have access to the right context to tie up with my unit of work so that changes get saved or dropped with the context save?
3) Is there a better way?
4) If you suggest I do this, any pointers would be appreciated - everything I've read is for validation, which may not be the best starting point.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实际上,验证可能是一个很好的起点。由于属性不知道它被分配给哪个属性或类,但验证框架会调用验证属性并提供所有必要的信息。如果实现 System.ComponentModel.DataAnnotations.ValidationAttribute 类,则可以重写 IsValid(object, ValidationContext) 方法,该方法为您提供属性的实际值、属性的名称和容器。
这可能需要大量工作,因为您需要访问当前登录的用户等。我猜测 .NET 实现为实体类型上的特定属性提供了某种缓存,这将是一个痛苦自己去实施。
另一种方法是使用 EF ObjectContext 公开的 ObjectStateManager,它可以为您提供给定状态的所有实体的 ObjectStateEntry 对象。请参阅
ObjectStateManager.GetObjectStateEntries(EntityState) 方法,了解有关如何调用它(以及何时)的更多信息。 ObjectStateEntry 实际上包含原始值和当前值的记录,可以将其进行比较以查找当前 ObjectContext 生命周期内所做的任何更改。
您可能会考虑使用 ObjectStateManager 注入自定义日志记录行为,而此行为根据属性决定应记录哪些更改。
Actually, validation might be a good starting point. Since an attribute does not know about which property or class it was assigned to, but a validation-attribute gets called by the validation framework with all the necessary informátion. If you implement the System.ComponentModel.DataAnnotations.ValidationAttribute class you can override the IsValid(object, ValidationContext) method, which gives you the actual value of the property, the name of the property and the container.
This might take a lot of work, since you need to get to the currently logged-in user etc. I'm guessing that the .NET implementation provides some sort of caching for the specific attributes on an entity type, which would be a pain to implement by yourself.
Another way, would be to use the ObjectStateManager exposed by your EF ObjectContext, which can provide you with the ObjectStateEntry-objects for all entities of a given state. See the
ObjectStateManager.GetObjectStateEntries(EntityState) method, for more information about how to call it (and when). The ObjectStateEntry actually contains a record of the original and current-values, which can be compared to find any changes made within the lifetime of the current ObjectContext.
You might consider using the ObjectStateManager to inject your custom logging behavior, while this behavior decides based on property-attributes which change should be logged.