Search code examples
c#entity-framework-4transactionstransactionscope

Understanding Transactions in Entity Framework


Hi I am trying to use transactions along with Entity Framework. With so much information available online on the different ways to implement transactions I must say I am a bit confused on the right way. I have an example database with two tables Employee and Company. The Employee table has a foreign key referring to the company Id. Considering I want to implement a transaction where I insert a record to the Company table and then a record to the Employee table and I want to do this so that records are inserted only if both are successful I have the following code.

public void addCompanyToDatabase()
    {
        using (var context = new myTestEntities())
        {
            context.Connection.Open(); //added this as was getting the underlying   
            //provider failed to open
            using (TransactionScope scope = new TransactionScope())
            {
                try
                {
                    Company c = new Company();
                    c.Name = "xyz";
                    context.Companies.AddObject(c);
                    context.SaveChanges();

                    //int a = 0;
                    //int b = 5 / a;

                    Employee e = new Employee();
                    e.Age = 15;
                    e.Name = "James";
                    e.CompanyId = c.Id;
                    context.Employees.AddObject(e);
                    context.SaveChanges();

                    scope.Complete();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception Occurred");
                }
            }
        }
    }

I wanted to know if this was the right way of implementing transactions. If it is then what is the use of the SaveChanges(false) and the scope.AcceptAllChanges() functions. Any information would be helpful.


Solution

  • In your case you don't need to manage any connection or transaction: Entity Framework will do this for you. When you don't supply EF with an opened connection (but with a connection string), it will open a connection and start a transaction during the call to context.SaveChanges(). When something fails during that call, the transaction will be rolled back.

    In other words, your method can simply look like this:

    public void addCompanyToDatabase()
    {
        using (var context = new myTestEntities())
        {
            Company c = new Company();
            c.Name = "xyz";
            context.Companies.AddObject(c);
    
            Employee e = new Employee();
            e.Age = 15;
            e.Name = "James";
            e.CompanyId = c.Id;
            context.Employees.AddObject(e);
    
            // Only call SaveChanges last.
            context.SaveChanges();
        }
    }