Search code examples
c#entity-frameworkentity-framework-4transactionscope

Using Transactions with EntityFramework FROM the business logic layer


Pls see this first: Good Coding Practices

So, this is my design.

  1. Website 2.Business Logic Layer 3.DALFacade (we use dalfacade to hide the data access, because we use 2 different stores, sql and db2) 4.DAL

In the DAL we use unit of work pattern and repository pattern. 1. The big question here is: If the code below will run ok for transactions that are created from the business logic.?

Page:

public partial class NewBonusRequest : System.Web.UI.Page
{

    #region Constructor and Instantiation of Business Logic
        /// <summary>
        /// Property that holds the Business Logic type to call methods
        /// </summary>
        public IRequestBL RequestBL { get; private set; }

        /// <summary>
        /// The default constructor will use the default implementation of the business logic interface
        /// </summary>
        public Request()
            : this(new RequestBL())
        {
        }

        /// <summary>
        /// The constructor accepts a IEcoBonusRequestFacade type
        /// </summary>
        /// <param name="ecoBonusRequestBL">IEcoBonusRequestFacade type</param>
        public NewRequest(IRequestBL RequestBL)
        {
            RequestBL = RequestBL;
        } 
    #endregion


    protected void PageLoad(object sender, EventArgs e)
    {
        if(!Page.IsPostBack)
        {

        }
    }


    #region Control Events
        protected void BtnSubmitRequestClick(object sender, EventArgs e)
        {
            var request= new Request
                                       {
                                           IsOnHold = true
                                           //All other properties go here.
                                       };

            RequestBL.Save(request);
        }



    Business Logic Code.

    public interface IRequestBL
    {
        void Save(Request request);
    }

    /// <summary>
    /// Class in charge of the business logic for EcoBonusRequest
    /// </summary>
    public class RequestBL : IRequestBL
    {
        /// <summary>


        /// <summary>
        /// Saves a new ecobonus request into database and evaluate business rules here
        /// </summary>
        /// <param name="ecoBonusWorkflow">EcoBonusWorkflow entity</param>
        public void Save(Request Request)
        {
            using (var scope = new TransactionScope())
            {
                Request.Save(request);
                // Call to other DALCFacade methods that insert data in different tables
                // OtherObject.Save(otherobject)
                scope.Complete();
            }
        }
    }

Solution

  • Yes in the same thread, EF will properly consider transaction scope if it exists. EF will not create new transaction if it's already in one.

    However, you must be careful because if you query your database without transaction then you will get dirty reads. Because EF will not read anything in transaction if it does not exist but it creates new transaction if it does not exist while saving changes.

    In your code you are only saving changes in transaction but you should be careful while reading and you should encapsulate your queries also in scope in smaller units.