[Expand]General Information
[Expand]WinForms Controls
[Expand]ASP.NET Controls and MVC Extensions
[Expand]ASP.NET Bootstrap Controls
[Expand]ASP.NET Core Bootstrap Controls
[Expand]WPF Controls
[Expand]Xamarin Controls
[Expand]Windows 10 App Controls
[Expand]Office File API
[Expand]Reporting
[Expand]Report and Dashboard Server
[Expand]Dashboard
[Expand]eXpressApp Framework
[Collapse]eXpress Persistent Objects
 [Expand]Product Information
 [Expand]Getting Started
 [Expand]Fundamentals
 [Expand]Feature Center
 [Collapse]Concepts
   Basics of Creating Persistent Objects for Existing Data Tables
   Creating a Persistent Object
   Creating a Session
   Creating an XPCollection
   Custom Collection Types
   Deferred and Immediate Object Deletion
   Explicit Units of Work
   Filtering Basics
   Generating Persistent Objects for Existing Data Tables
   How to: Add Persistence to an Existing Hierarchy by Changing the Base Inheritance
   How to: Add Persistence to an Existing Hierarchy by Using Session-less Persistent Objects
   How to: Connect to a Data Store
   Inheritance Mapping
   Nested Units of Work
   NULL Value Handling Specifics
   Optimistic Concurrency Control
   Pageable Collections
   Property Descriptors
   Relationships Between Objects
   Saving Persistent Objects
   Simplified Criteria Syntax
   Simplified Property Syntax
   Sorting Basics
   Using Explicit Transactions
   Using Transactions
   Value Converters
   Working with Sessions
   XPCollection Concepts
   XPDataView Concepts
   XPO Classes Comparison
   XPView Concepts
 [Expand]Design-Time Features
 [Expand]Examples
 [Expand]Member Tables
 [Expand]API Reference
[Expand]CodeRush
[Expand]CodeRush Classic
[Expand]Cross-Platform Core Libraries
[Expand]Tools and Utilities
 End-User Documentation
View this topic on docs.devexpress.com (Learn more)

Explicit Units of Work

An explicit unit of work is a Unit of Work descendant that uses long explicit transactions to isolate object changes at the database level. Because of this, persistent objects are temporarily stored in a database, allowing you to access these objects as if they were already stored in the database.

Important

An Explicit Unit of Work that starts an explicit transaction must be the exclusive owner of the database connection. Therefore, only one explicit transaction can be open at a time. That's why you cannot use an Explicit Unit of Work within another Explicit Unit of Work. However, you can create Nested Units of Work within an Explicit Unit of Work, if necessary.

Expanded Managing Explicit Transactions

Within an explicit unit of work, you can execute transaction commands (start an explicit transaction, commit all temporary changes or roll them back) at any time, just like regular transactions, using methods displayed in the following table.

Transaction Command

Method

BEGIN

ExplicitUnitOfWork.BeginTransaction

COMMIT

ExplicitUnitOfWork.CommitTransaction

UnitOfWork.CommitChanges

UnitOfWork.CommitChangesAsync

ExplicitUnitOfWork.CommitTransactionAsync

ROLLBACK

ExplicitUnitOfWork.RollbackTransaction

As with regular transactions, the BEGIN command marks the point at which the data referenced by an explicit unit of work is consistent. All data modifications made after this command can be rolled back. This allows data to be returned to this known state of consistency. Each transaction lasts until either the COMMIT or ROLLBACK command is executed. The COMMIT command writes the modifications. The ROLLBACK command discards all the changes made.

To make things simple, an explicit unit of work automatically starts an explicit transaction before data modifications are temporarily saved to a database for the first time. So, there is no need to start an explicit transaction manually within an explicit unit of work.

Expanded Managing Object Changes

Like normal units of work, explicit units of work automatically track all changes made to persistent objects. Due to the explicit transactions, you can access modified objects without having to commit the changes beforehand. As shown in the example above, the newly created Person object is retrieved by the Session.FindObject function, as if it was already stored in a database.

In addition, you can manually manage changes within an explicit unit of work via the Session.DropChanges, Session.FlushChanges, and Session.FlushChangesAsync methods, as shown in the example below.

Note

Methods performing transaction operations (see the table in the previous section) automatically call Session.DropChanges (ROLLBACK) or Session.FlushChanges (BEGIN OR COMMIT) for your convenience.

Managing object changes using explicit units of work is handy when intermediate object updates may violate database constraints. So to avoid constraint violations, all intermediate object changes are applied temporarily within an explicit unit of work, using Session.FlushChanges.

Consider an example when a field has a unique constraint in the database, and you need to make changes that can violate these constraints. In other words, you need to remove the object and create a new one, but with the same identifier. The code below shows how this can be accomplished. Note that the Oid key field is not auto-incremented.

Note that when using explicit units of work, your persistent classes should not make database queries from IXPObject.OnSaving method overloads. Thus, you cannot modify an object state via the OnSaving method.

Expanded See Also

Is this topic helpful?​​​​​​​