开发者

NHibernate persist object changes for approval

I am building an application that allows users to make changes to objects, but the changes have to be approved before they are made permanent. I am using NHibernate.

How would you handle this sort of scenario using? Are there any articles out there that tackle this issue?

I am thinking of having two tables for each object. One for the current state and one for the proposed state. Then having a Generic ChangeRequest object that would specify the Delete/Insert/Update and the subject that wants to be changed. But, I don't believe NHibernate will allow you to have two different mappings for the sa开发者_如何学Gome object.


The two options off the top of my head...

Each object could have an approved flag or approved date. (This could be encapsulated in a common base class.) You would either need a composite key including the approval column (not recommended - composite keys are a pain) or each object could have a business key in addition to the PK. This would mean one table per entity with some extra metadata columns in each table to determine approved. (You could decide whether to keep all changes or only the latest.)

The other option would be two separate tables for each object. You can do this using Entity Names, which were introduced in NH2.1. Easiest to show an example. We have only one class definition:

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

We have two hbm.xml files. Note the entity-name attribute after the class. This creates two tables, Foo1 and Foo2. (You could pick your own names via the table attribute.)

<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>

When we save the entities, we provide the entity-name with the operation:

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

This allows you to select which table the entity goes to. You would of course want to encapsulate the entity names in a constants class. You need to specify the entity name for all operations (session.Get(), session.Save(), session.Update(), session.Delete(), etc.)


For your case I would suggest that each object will have the following design: PropertyName, PropertyValue, PropertyStatus (propesed/approved). By this desing you can alter your objects in any way while keeping one mapping for the file. For example if a person table should have the columns ssn, name, birthdate .... In this desing you will have 3 rows:

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

Think of it as if it is a vertical table where rows are column and vice versa.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜