eXpress Persistent Objects can perform semi-automatic change tracking using the Unit of Work principle. Unit of Work maintains a list of persistent objects that are affected by a transaction. It keeps track of every change to every persistent object during a transaction that can affect a data store. With a single call to the UnitOfWork.CommitChanges method, all the changes made to the persistent objects are automatically saved to a data store. When working with common sessions, you need to save each persistent object individually.

Unit of Work is represented by a UnitOfWork or ExplicitUnitOfWork class. These classes inherit the base functionality from the Session class and provide the UnitOfWork.CommitChanges method that is used to save all changed persistent objects to a data store. The only requirement for this is that the property setters call the XPBaseObject.OnChanged method. To simplify things, you can call the SetPropertyValue method to meet the requirement, as shown below.

Declaring a Persistent Object

 

public class UOWPerson : XPObject
{
    string fName;
    public UOWPerson(Session session) : base(session) { }
    public UOWPerson(Session session, string name) : base(session)
    {
        this.fName = name;
    }
    public string Location { 
        get { return GetPropertyValue<string>("Location"); }
        set { SetPropertyValue<string>("Location", value); }
    }
    public string Name {
        // We cannot use GetPropertyValue in the getter  
        // below because the fName field is explicitly defined 
        get { return fName; }
        set { SetPropertyValue<string>("Name", ref fName, value); }
    }
}
NoteNote

SetPropertyValue automatically calls the XPBaseObject.OnChanged method to track changes made to the Name and Location properties. Once Unit of Work's UnitOfWork.CommitChanges method is called, the changes will be automatically saved to a data store. You should always implement properties this way, if you wish changes to be recognized automatically in Units of Work.

 

Using Units of Work in XPO

The following sample creates a new instance of the UnitOfWork class (uow object) with default settings. In this case, there is no specific rollback code and the changes are only committed to the database if the UnitOfWork.CommitChanges method is executed. The UnitOfWork class derives from Session and thus all objects that are being handled within a unit must be fetched via that unit or associated with it by means of the session constructors in the XPO base classes.

using(UnitOfWork uow = new UnitOfWork()) {
    // Create, update or delete objects 
    uow.CommitChanges();
}

After this we create three persistent objects of the UOWPerson type that has been declared above. If the Session has been used, then we save each persistent object individually by calling its XPBaseObject.Save method. While using Unit of Work, only one UnitOfWork.CommitChanges method call is needed to save all the made changes.

using(UnitOfWork uow = new UnitOfWork()) {
    UOWPerson p = new UOWPerson(uow, "Mike");
    // p.Save(); when working with a Session 

    p = new UOWPerson(uow, "John");
    // p.Save(); when working with a Session 

    p = new UOWPerson(uow);
    p.Name = "Bob";
    p.Location = "US";
    // p.Save(); when working with a Session 

    // Save all the changes made 
    uow.CommitChanges();
}

Internally, the UnitOfWork class uses a single transaction that is started automatically, committed in the UnitOfWork.CommitChanges method, and rolled back when the unit is being disposed.

 

 

posted on 2011-10-15 22:11  随心飞翔  阅读(394)  评论(0)    收藏  举报