我该如何在ASP.NET MVC (NHibernate)中跟踪任何对象的更改?

4
我正在寻找一种好的方法来跟踪对象上所做的每一个更改。
我们正在构建一个自定义框架,我们需要有一个关于谁在什么时候更改了哪个对象以及可能是什么的历史记录(类似的)。
在这种情况下,什么是好的做法?
扩展保存/更新方法以编写“日志”? 我应该尝试使用log4net或类似的日志扩展吗?
我担心扩展保存/更新/例程会带来额外负担。
编辑: 是的,我需要至少查看一个月的更改记录,客户有时会抱怨数据丢失,而他们“忘记”删除它...
编辑2(为了更好地理解,在评论中提出的问题): 历史记录应存储在数据库(ms sql)中,我不想在每个类的每个操作中添加日志记录。 所有类都继承自我的基类,该基类提供保存、加载、更新、删除等功能... 感谢进一步的答案/评论 :)
4个回答

2
你基本上在寻找审计解决方案,是吗?我知道Hibernate有使用名为Hibernate Envers的附加项目来实现它。我在这篇博客文章中找到了最快的信息。至于NHibernate,我相信已经在将Envers移植到NHibernate上进行工作,以便将该功能也用于.NET社区。
我认为在深入研究其他解决方案之前先了解一下它的预计完成时间会很有价值。如果你可以将其集成到ORM中,那就太好了,不是吗?;-)
我刚刚快速检查了一下,我想Tuna Toksoz正在处理这个问题,至少根据他的Twitter消息是这样的。

随着我深入研究我的问题,审计日志似乎是我需要的,没错。 Envers听起来真不错,而且灵活性看起来完美。但我找不到任何关于.Net端口的严肃信息,Tuna Toksoz也没有博客文章...我还阅读了(http://nhforge.org/wikis/howtonh/creating-an-audit-log-using-nhibernate-events.aspx),这看起来像是我自己完成它的可能方式。 - griti
感谢@Erik van Brakel,你已经为我节省了大量手动配置日志的工作! - Rowan

0

我假设你正在使用关系型数据库作为数据存储。

你一定需要向数据库添加一个历史记录表,该表与原实体具有几乎相同的表结构。

该表中的每一行都会得到原始(活动)实体的外键和时间戳,因此您现在知道更改的顺序。稍后,您可以通过原始ID从表中检索所有历史信息,按时间戳排序,然后基于更改创建一些自定义日志消息(考虑反射)。

但是,您必须决定您的更改跟踪应该遍历对象图的“深度”(跟踪关系等方面的更改)。

在每次更新时,您将原始行复制到历史记录表中,引用原始行并添加时间戳,然后再更新原始行。

您可能希望对更新使用存储过程来封装此操作。


是的,我使用关系型数据库(目前是SQL Server 2005)。还需要跟踪关系(例如,从用户y添加到x的产品描述)。 - griti

0
你需要多长时间的历史记录?如果答案超过了应用程序实例的时间,那么你必须走数据库路线。如果是这种情况,我会在数据库层面处理所有内容,而不是在代码中处理。也许触发器是你的好朋友...

好的,我会进一步检查还原历史记录条目和其他方面的可用性。在数据库层面上,我仍然需要为所有对象创建历史记录部分,有时每个对象需要涉及3个或更多的表... 唉 <: - griti
就我所了解的客户需求,历史记录应该在应用程序级别与nHibernate一起完成。使用触发器和nHibernate可能是一种解决方案,但不适用于我的情况。 - griti

0

假设您正在使用关系型数据库,您可以简单地在插入、更新和删除事件上编写触发器,以在另一个表中编写操作或其他内容。

根据我的看法,使用与原始数据表相同定义的历史记录表也是一个好主意。这使您可以尽可能轻量化您的原始表,在数据库中增加DQL对表的性能,并且在跟踪用户意外删除的记录时,您不需要获取每个记录。

另一种方法是,根据每天处理的行数,您可以简单地标记一个字段为true或false,无论它是否被删除,并添加一个列来保存当前执行操作的用户。假设您已经配置了DB以与Active Directory一起工作,以便您可以精确识别当前用户。

在写作时,我遇到了另一个想法。您可能已经自己考虑过了! :-) 无论如何,您可以构建一个管理安全事项的DLL。在您的代码中,您可以通过安全DLL传递一个参数,其中包含当前登录的用户。

无论如何,我认为log4net是一个不错的选择。您可以将每个用户的事件记录到SQLite数据库中,这是个人版的免费数据库。如果我没记错的话,Microsoft Enterprise Library 4.1 - 2008年10月,提供了非常有用的工具,作为程序员,需要一遍又一遍地重写代码变得极为乏味。MEL特别设计来使这些可重复的例程更容易避免反复重写代码的痛苦。这让您专注于客户所需的功能和要求。它是开源的,并由微软维护,以满足IBM、HP等大公司的需求,可能还有我们仍不知道存在的一些公司。总之,我认为Enterprise Library可能是最好的选择,始终考虑您的架构,因为它几乎只能通过配置来使用。
如果您习惯于反射,还可以通过反射初始化对象实例,在保存时同时记录日志的例程。
正如您所看到的,有许多方法可以使您轻松实现它。这完全取决于您的架构。
嗯,我写了很多。希望不会让任何人感到无聊!:-)
祝你有愉快的一天!

触发器是一种方式,但我还需要在 nhibernate 中映射所有内容才能加载它(“正确”的方式)。当然,使用反射会更加灵活,因此我将考虑整个跟踪/日志记录,并确保检查客户想要/支付的内容 ;) - griti
我还想在应用程序级别上进行日志记录/触发,忘记在我的评论中提到了 :-) - griti
我了解企业库日志记录功能。主要来说,企业库只需要正确的配置就可以正常工作。我想这可能是一个有趣的探索方式。 - Will Marcouiller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接