我正在构建一个允许用户对对象进行更改的应用程序,但这些更改必须在永久更改之前获得批准。我正在使用NHibernate。
你将如何处理这种情况?是否有任何文章可以解决这个问题?
我想为每个对象设置两个表。一个用于当前状态,一个用于建议状态。然后有一个Generic ChangeRequest对象,它指定删除/插入/更新和想要更改的主题。但是,我不相信NHibernate会允许你为同一个对象提供两种不同的映射。
答案 0 :(得分:1)
我头顶的两个选项......
每个对象都可以拥有批准的标志或批准的日期。 (这可以封装在一个公共基类中。)您需要一个包含批准列的复合键(不推荐 - 复合键很痛苦),或者每个对象除了PK之外还可以有一个业务键。这意味着每个实体有一个表,每个表中有一些额外的元数据列以确定已批准。 (您可以决定是保留所有更改还是仅保留最新更改。)
另一个选项是每个对象的两个单独的表。您可以使用NH2.1中引入的实体名称来执行此操作。最容易展示一个例子。我们只有一个类定义:
public class Foo {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
我们有两个hbm.xml文件。请注意类之后的entity-name属性。这会创建两个表,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()等。)
答案 1 :(得分:0)
对于您的情况,我建议每个对象具有以下设计:PropertyName,PropertyValue,PropertyStatus(propesed / approved)。通过这种设计,您可以以任何方式更改对象,同时保留文件的一个映射。 例如,如果一个人表应该有列ssn,name,birthdate ....在这个设计中你将有3行:
In regular design ----------------- ColumnName ColumnValue ID 1 ssn 123 name xyz birthdate dd/mm/yyy This will be ------------ PropertyName PropertyValue ObjectID PropertyStatus ssn 123 1 approved name xyz 1 approved birthdate dd/mm/yyyy 1 approved
将其视为一个垂直表,其中行是列,反之亦然。