Loading...
Area: Episerver B2B Commerce

IUnitOfWork

Recommended reading 

Description

The IUnitOfWork interface is the abstraction layer to the object session management of the system.

The first time the UnitOfWork is accessed, it will create an instance of the UnitOfWork in HttpContext.Current.Items which lasts for the current web request. Subsequent access of UnitOfWork will return this instance.

Properties

DataProvider

The Persistant Data Provider.

IDataProvider DataProvider {get;}

Methods

BeginTransaction()

This method starts a Database Transaction.

void BeginTransaction()

Example

Below is the typical usage of this method along with the other methods that handle the lifetime of a database transaction.

Code Sample

this.UnitOfWork.BeginTransaction();
try
{
    foreach (var contentKey in contentKeys)
    {
        this.RecursiveDelete(contentKey, isVariant);
    }
 
    this.UnitOfWork.Save();
    this.UnitOfWork.CommitTransaction();
}
catch (Exception)
{
    this.UnitOfWork.RollbackTransaction();
    throw;
}

BeginTransaction(IsolationLevel)

This method starts a Database Transaction using the specified isolation level.

void BeginTransaction(IsolationLevel isolationLevel)

Parameters

  • isolationLevel - Isolation level.

Clear(bool)

This method clears the objects out of the UnitOfWork session, the objects will still be valid objects, but they will no longer be persisted to the database. This method is useful when working with large sets of data for example during a refresh.

void Clear(bool dispose = true)

Parameters

  • dispose - If true, the underlying data provider will be disposed.

Close()

Close the Session.

void Close()

CommitTransaction()

Commits a previously started Database Transaction.

void CommitTransaction()

EagerLoad(object)

Forces a load of a proxy, does not cascade.

void EagerLoad(object obj)

Parameters

  • obj - The obj.

Evict(object)

Removes a single object from the UnitOfWork session. The object is still a valid object, but will no longer persist to the database.

void Evict(object obj)

Parameters

  • obj - The obj.

GetRepository(Type)

Returns an IRepository for an object that will be tracked within this UnitOfWork's session.

IRepository GetRepository(Type type)

Parameters

  • type - The type.

Returns

  • The IRepository.

GetRepository<T>()

Returns an IRepository for an object that will be tracked within this UnitOfWork's session.

IRepository<T> GetRepository<T>()

Returns

  • The IRepository.

Type Constraints

  • T : class, IBusinessObject

Remarks

Unlike the GetTypedRepository<T> method, this method returns a generic repository, rather than a specific repository, that operates on a specific business object.

Example

The example below uses the GetRepository<T> method to return an IRepository<CustomerOrder> to delete a specific customer order.

Code Sample

public override RemoveCartResult Execute(IUnitOfWork unitOfWork, RemoveCartParameter parameter, RemoveCartResult result)
{
    var cart = result.GetCartResult.Cart;
    if (cart.Id == Guid.Empty || cart.Status == CustomerOrder.StatusType.Void)
    {
        return this.NextHandler.Execute(unitOfWork, parameter, result);
    }
 
    unitOfWork.GetRepository<CustomerOrder>().Delete(result.GetCartResult.Cart);
 
    return this.NextHandler.Execute(unitOfWork, parameter, result);
}

GetTypedRepository<T>()

Returns a specific type of IRepository that will be tracked within this UnitOfWork's session.

T GetTypedRepository<T>()

Returns

The repository.

Type Constraints

T : class, IRepository

Remarks

This method is useful if you need to use a method on a repository that is specific to that repository implementation. For example, the IUserProfileRepository has a method GetByUserName that finds a user by username rather than by id, which is another way to retrieve an object from the database.

Example

The example below validates the email address when creating a new account. The GetTypedRepository<T>() method is used to return the IUserProfileRepository and check if the email address is already being used by another user.

Code Sample

public override AddAccountResult Execute(IUnitOfWork unitOfWork, AddAccountParameter parameter, AddAccountResult result)
{
    if (!RegularExpressionLibrary.IsValidEmail(parameter.Email))
    {
        return this.CreateErrorServiceResult(
            result,
            SubCode.InvalidEmailAddress,
            MessageProvider.Current.UpdateAccountInfo_EmailAddress_ValidEmail);
    }
 
    if (this.authenticationService.Value.RequiresUniqueEmail())
    {
        var emailAlreadyExists = unitOfWork.GetTypedRepository<IUserProfileRepository>().GetTable().Any(o => o.Email.Equals(parameter.Email));
 
        if (emailAlreadyExists)
        {
            return this.CreateErrorServiceResult(
                result,
                SubCode.AccountServiceEmailAlreadyExists,
                MessageProvider.Current.CreateNewAccountInfo_EmailAddress_AlreadyExists);
        }
    }
 
    return this.NextHandler.Execute(unitOfWork, parameter, result);
}

Reattach<T>(T)

Reattaches a previously Evicted object to the session.

void Reattach<T>(T value)

Parameters

  • value - The value.

Type Constraints

  • T : class, IBusinessObject

Refresh<T>(T)

Refresh an object from the database.

void Refresh<T>(T obj)

Parameters

  • obj - The obj.

Type Constraints

  • T : class, IBusinessObject

RollbackTransaction()

Rolls back a previously started Database Transaction

void RollbackTransaction()

Save()

Saves all of the changes in the current UnitOfWork session to the Database.

void Save()

Remarks

This method is typically called after updating or deleting existing business objects or creating new business objects.

Example

The example below adds a new bill-to customer based on data sent along with the API request.

Code Sample

public override AddBillToResult Execute(IUnitOfWork unitOfWork, AddBillToParameter parameter, AddBillToResult result)
{
    var customerRepository = unitOfWork.GetRepository<Customer>();
 
    var billTo = customerRepository.Create();
    var setBillToInitialValuesResult = this.customerPipeline.SetBillToInitialValues(new SetBillToInitialValuesParameter(billTo));
    if (setBillToInitialValuesResult.ResultCode != ResultCode.Success)
    {
        return this.CreateErrorServiceResult(result, setBillToInitialValuesResult.SubCode, setBillToInitialValuesResult.Message);
    }
 
    billTo.IsGuest = parameter.IsGuest;
    billTo.FirstName = parameter.FirstName ?? string.Empty;
    billTo.LastName = parameter.LastName ?? string.Empty;
    billTo.CompanyName = parameter.CompanyName ?? string.Empty;
    billTo.Attention = parameter.Attention ?? string.Empty;
    billTo.Address1 = parameter.Address1 ?? string.Empty;
    billTo.Address2 = parameter.Address2 ?? string.Empty;
    billTo.Address3 = parameter.Address3 ?? string.Empty;
    billTo.Address4 = parameter.Address4 ?? string.Empty;
    billTo.City = parameter.City ?? string.Empty;
    billTo.PostalCode = parameter.PostalCode ?? string.Empty;
    billTo.Phone = parameter.Phone ?? string.Empty;
    billTo.Fax = parameter.Fax ?? string.Empty;
    billTo.Email = parameter.Email ?? string.Empty;
 
    this.customerUtilities.SetCountry(unitOfWork, parameter.CountryId, billTo);
    this.customerUtilities.SetState(unitOfWork, parameter.StateId, billTo);
 
    customerRepository.Insert(billTo);
    unitOfWork.Save();
 
    result.BillTo = billTo;
 
    return this.NextHandler.Execute(unitOfWork, parameter, result);
}

SaveAsync()

Saves all of the changes in the object in the current UnitOfWork session to the Database async.

Task SaveAsync()

Returns

  • The Task.

SaveWithoutChangeTracking(Action)

Saves all of the changes in the current UnitOfWork session to the Database executing the passed in action while Change Tracking is disabled.

void SaveWithoutChangeTracking(Action action)

Parameters

  • action - The action.

UnProxy(object)

Convert a proxied object into the real thing.

object UnProxy(object obj)

Parameters

  • obj - The obj.

Returns

  • The object.

Do you find this information helpful? Please log in to provide feedback.

Last updated: Dec 11, 2020

Recommended reading