【问题标题】:NHibernate persist object changes for approvalNHibernate 持久化对象更改以供批准
【发布时间】:2010-12-01 20:48:53
【问题描述】:

我正在构建一个允许用户对对象进行更改的应用程序,但这些更改必须在永久生效之前获得批准。我正在使用 NHibernate。

您将如何处理这种情况?有没有解决这个问题的文章?

我正在考虑为每个对象设置两个表。一个用于当前状态,一个用于建议状态。然后有一个通用的 ChangeRequest 对象,它将指定删除/插入/更新和要更改的主题。但是,我不相信 NHibernate 会允许你对同一个对象有两个不同的映射。

【问题讨论】:

    标签: nhibernate domain-driven-design


    【解决方案1】:

    我脑海中的两个选项......

    每个对象都可以有一个批准标志或批准日期。 (这可以封装在一个公共基类中。)您可能需要一个包含批准列的组合键(不推荐 - 组合键很麻烦),或者每个对象除了 PK 之外还可以有一个业务键。这意味着每个实体有一个表,每个表中有一些额外的元数据列来确定是否批准。 (您可以决定是保留所有更改还是仅保留最新更改。)

    另一个选项是每个对象有两个单独的表。您可以使用 NH2.1 中引入的实体名称来执行此操作。最容易展示一个例子。我们只有一个类定义:

    public class Foo {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
    }
    

    我们有两个 hbm.xml 文件。注意类后面的实体名称属性。这将创建两个表,Foo1 和 Foo2。 (您可以通过 table 属性选择自己的名字。)

    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NhHacking" assembly="NhHacking">
      <class name="Foo" entity-name="Foo1">
        <id name="Id">
          <generator class="native" />
        </id>
        <property name="Name"/>
      </class>
    </hibernate-mapping>
    
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="NhHacking" assembly="NhHacking">
      <class name="Foo" entity-name="Foo2">
        <id name="Id">
          <generator class="native" />
        </id>
        <property name="Name"/>
      </class>
    </hibernate-mapping>
    

    当我们保存实体时,我们为实体名称提供操作:

    var foo1 = new Foo {Name = "Foo1"};
    var foo2 = new Foo {Name = "Foo2"};
    session.Save("Foo1", foo1);
    session.Save("Foo2", foo2);
    

    这允许您选择实体去哪个表。您当然希望将实体名称封装在常量类中。您需要为所有操作(session.Get()、session.Save()、session.Update()、session.Delete() 等)指定实体名称

    【讨论】:

    • 我不知道您可以将同一个类映射到两个映射。这大概就是我要处理的方式。我可以在 ChangeRequest 对象映射文件中指定用于 的实体名称吗?这样,我可以在 ChangeRequest 上调用 save ,它会将 保存到等待批准表中。
    • 据我所知,您无法开箱即用。您需要为每个 ChangeRequest 创建一个单独的 hbm.xml 文件。通过对 Configuration 对象进行一些元编程来解决这个问题并不难。阅读您的配置后,您可以修改您的 Configure.ClassMappings 以包含实体名称,然后克隆每一个 - 将实体名称修改为 ChangeRequest - 并将其添加到 Configure.ClassMappings 集合中。从来没有这样做过,但它应该可以工作......
    【解决方案2】:

    对于您的情况,我建议每个对象都具有以下设计:PropertyName、PropertyValue、PropertyStatus(propesed/approved)。通过这种设计,您可以以任何方式更改对象,同时为文件保留一个映射。 例如,如果一个人表应该有列 ssn、姓名、生日...。在这个设计中,您将有 3 行:

    在常规设计中 ----------------- 列名 列值 编号 1 ssn 123 名称 xyz 生日 dd/mm/yyy 这将是 ------------ PropertyName PropertyValue ObjectID PropertyStatus ssn 123 1 批准 名称 xyz 1 已批准 生日 dd/mm/yyyy 1 批准

    把它想象成一个垂直表,其中行是列,反之亦然。

    【讨论】:

      猜你喜欢
      • 2017-04-03
      • 2011-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-01
      • 1970-01-01
      相关资源
      最近更新 更多