As discussed in Architecture & Patterns, LightSpeed uses the Unit of Work pattern as a way of organizing logical sets of database operations.

A unit of work in LightSpeed is primarily two things:

  1. A database connection
  2. An Identity Map of references to the entities currently in memory.

Typically, you will create a unit of work per thread (in a Windows application) or a unit of work per request (in a Web application). However, you can create multiple units of work within the same thread or request if you need to do so. A unit of work should not be shared between threads as it encapsulates non-thread-safe resources such as database connections. A unit of work is designed to be short-lived: typically you will create the unit of work, load and/or modify some data, save changes if required, and then dispose of the unit of work.

To create a unit of work, call LightSpeedContext.CreateUnitOfWork.

As entities are loaded from the database through the IUnitOfWork.Find method, and new entities are added through the IUnitOfWork.Add method, they become tracked by this unit of work. If any of the entities are modified they will be automatically persisted during the next save operation.

To save the changes in a unit of work, call IUnitOfWork.SaveChanges.

To dispose of a unit of work and free associated resources, call IUnitOfWork.Dispose.

Unit of Work Scoping

LightSpeed can automatically create and dispose units of work for you based on the common patterns mentioned above. To do this, instead of creating a unit of work explicitly using LightSpeedContext.CreateUnitOfWork, create a UnitOfWorkScopeBase and access the UnitOfWorkScopeBase.Current property.

To have units of work created and disposed on a per-Web-request basis, use PerRequestUnitOfWorkScope. See the ASP.NET MVC sample for an example of how to use PerRequestUnitOfWorkScope in a model-view-controller Web application.

Scope classes support strong-typed units of work for ease of use with LINQ.

Attaching Entities to a new Unit of Work

Sometimes an application will need to hold a reference to an entity after the unit of work associated with the entity has been completed. For example, maybe the entity has been held in ASP.NET Session state. To support this scenario, LightSpeed provides the IUnitOfWork.Attach method. This method allows you associate an entity with a new unit of work. The entity then becomes tracked like any other entity associated with that unit of work.

Ad Hoc Changes

Sometimes an application will want to modify data in the database without loading it into entities, modifying those entities and saving the changes back. This is most likely in the case of batch/bulk updates or deletes. For this functionality see IUnitOfWork.Update and IUnitOfWork.Remove. Please note the caveats in the method documentation.

Long Running Units of Work and Database Optimisation

As mentioned above, a unit of work is designed to be short-lived. However, in some rich client designs, it may be necessary or convenient to keep the unit of work alive for a relatively long time. In this case, the default behaviour of keeping a single connection open for the entire life of the unit of work can cause problems, such as connection starvation or brittleness in the face of intermittent connection errors. In such cases, you can create a custom connection strategy that allows your application finer control over the connection lifecycle, and apply it to the unit of work via UnitOfWork.ConnectionStrategy. For more information about using connection strategies, please see the online article Database connection strategies in LightSpeed 3.