如何在 NHibernate 中进行通用字段和组件级更改跟踪?

发布于 2024-08-06 17:16:08 字数 1840 浏览 3 评论 0原文

在我的应用程序中,我有一些不同类型的实体,我需要对其进行字段级更改跟踪。我已经在谷歌上搜索过这一点,只能提供一些关于执行简单的“插入日期”和“更新日期”审核跟踪的示例,您只需修改已经保存的实体上的字段。我的要求更复杂,因为:

  1. 我需要创建表示更改的新实体,而不仅仅是修改正在保存的实体上的字段(与我找到的插入日期、更新日期示例一样)
  2. 我需要将这些新实体保存到数据库在更新跟踪实体的同一事务中,
  3. 我需要跟踪附加到跟踪实体的 ValueObject 集合的更改,
  4. 我不想为每个跟踪实体编写单独的日志记录代码

示例代码:

public interface ITrackChanges {}
{
}

public class Account : ITrackChanges
{
    public int Id;
    public string AccountNumber;
    public string CustomerName;
    public string CustomerAddress;
}

public class Computer : ITrackChanges
{
    public int Id;
    public string AssetTag;
    public string SerialNumber;
    public IEnumerable<IPAddress> IPAddresses;
}

public class IPAddress : ValueObject
{
    public string Address;
}

每当 Account 或计算机对象更改或与计算机对象关联的 IP 地址列表更改,我需要创建并保存这些实体更改记录:

public class EntityChange
{
    public string EntityType;
    public string EntityId;
    public string PropertyName;
    public string OldValue;
    public string NewValue;
}

每个跟踪实体都实现 ITrackChanges 标记接口,每个值对象都继承自 ValueObject 基类。值对象被映射为 NHibernate 中的组件。

作为我希望获得的最终结果的示例,如果我使用 Id 1 更新计算机对象,并将 AssetTag 从“ABC123”更改为“ABC124”,并将 IP 地址列表从 {“1.2.3.4 " } 到 { "1.2.3.4" , "1.2.3.5" },我应该得到 2 条 EntityChange 记录:

EntityChange #1
{
    EntityType = "Computer"
    EntityId = 1
    PropertyName = "AssetTag"
    OldValue = "ABC123"
    NewValue = "ABC124"
}

EntityChange #2
{
    EntityType = "Computer"
    EntityId = 1
    PropertyName = "IPAddresses"
    OldValue = "1.2.3.4"
    NewValue = "1.2.3.4, 1.2.3.5"
}

关于实现这个的最佳方法有什么想法吗?从我对文档的阅读来看,我似乎需要编写一个拦截器和/或事件侦听器,但除了一些仅修改正在更新的实体之外,我无法找到任何示例。任何答案中都绝对欢迎示例代码。

我假设这应该是 NHibernate 支持的东西是错误的吗?我能够在之前使用 LLBLGen 作为 ORM 的应用程序中实现此功能,但这是我第一次必须在使用 NHibernate 的应用程序中实现此功能。

In my application, I've got a few different types of entities that I have a requirement to do field-level change tracking on. I've googled for this and only can come up with examples on doing simple "Date Inserted" and "Date Updated" audit tracking where you just modify fields on the entity being persisted already. My requirements are more complex because:

  1. I need to create new entities representing the changes not just modify fields on the entity being saved (as with the Date Inserted, Date Updated examples I've found)
  2. I need to save these new entities to the DB in the same transaction updating the tracked entity
  3. I need to track changes to collections of ValueObjects attached to the tracked entity
  4. I don't want to have to write seperate logging code for every tracked entity

Example code:

public interface ITrackChanges {}
{
}

public class Account : ITrackChanges
{
    public int Id;
    public string AccountNumber;
    public string CustomerName;
    public string CustomerAddress;
}

public class Computer : ITrackChanges
{
    public int Id;
    public string AssetTag;
    public string SerialNumber;
    public IEnumerable<IPAddress> IPAddresses;
}

public class IPAddress : ValueObject
{
    public string Address;
}

Whenever any of the values of an Account or Computer object changes or the list of IPAddresses associated with a Computer object changes, I need to create and save these entity change records:

public class EntityChange
{
    public string EntityType;
    public string EntityId;
    public string PropertyName;
    public string OldValue;
    public string NewValue;
}

Each tracked entity implements the ITrackChanges marker interface and each value object inherits from the ValueObject base class. The value objects are mapped as components in NHibernate.

As an example of what I'm looking to get as the end result, if I update the Computer object with Id 1 and change the AssetTag from "ABC123" to "ABC124" and change the list of IP addresses from { "1.2.3.4" } to { "1.2.3.4" , "1.2.3.5" }, I should get 2 EntityChange records:

EntityChange #1
{
    EntityType = "Computer"
    EntityId = 1
    PropertyName = "AssetTag"
    OldValue = "ABC123"
    NewValue = "ABC124"
}

EntityChange #2
{
    EntityType = "Computer"
    EntityId = 1
    PropertyName = "IPAddresses"
    OldValue = "1.2.3.4"
    NewValue = "1.2.3.4, 1.2.3.5"
}

Any ideas on the best way to implement this? From my reading of the docs, it looks like I need to write an interceptor and/or event listener but I haven't been able to find any examples beyond some that just modify the entity being updated. Example code is definitely welcome in any answers.

Am I wrong in assuming that this should be something supported by NHibernate? I was able to implement this in a previous application that used LLBLGen as the ORM but this is the first time I've had to implement this in an application using NHibernate.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泅人 2024-08-13 17:16:08

你想要的是使用会话拦截器。
您可以找到使用此进行审核的示例 此处

另外,您可能会从 NHibernate 邮件列表

What you want is to use a session Iinterceptor.
you can find a sample of using this for Auditing here

Also you will probably get more of a response from the NHibernate mail list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文