Skip to main content
A newer version of this page is available. .

Unit of Work

  • 4 minutes to read

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>(nameof(Location)); }
        set { SetPropertyValue<string>(nameof(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>(nameof(Name), ref fName, value); }
    }
}

Note

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 (or rolled back when the unit is being disposed).

Note

You can try the functionality described here in the Data Exchange and Manipulation | UnitsOfWork section of the XPO Tutorials demo (C:\Users\Public\Documents\DevExpress Demos 19.2\Components\WinForms\Bin\XpoTutorials.exe).

See Also