Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 929
nighthawk457 Avatar asked Nov 26 '11 00:11

nighthawk457


People also ask

What are the transactions in Entity Framework?

A transaction is a series of operations performed as a single unit of work. Entity Framework transactions are a part of its internal architecture. The SaveChanges method operates within a transaction and saves results of the work. It is designed to ensure data integrity.

How do I use transactions in EF core?

This feature was introduced in EF Core 5.0. When SaveChanges is invoked and a transaction is already in progress on the context, EF automatically creates a savepoint before saving any data. Savepoints are points within a database transaction which may later be rolled back to, if an error occurs or for any other reason.

Can you have transaction support in Entity Framework?

Entity Framework internally maintains transactions when the SaveChanges() method is called. It means the Entity Framework maintains a transaction for the multiple entity insert, update and delete in a single SaveChanges() method. When we execute another operation, the Entity Framework creates a new transaction.

How do I rollback a transaction in Entity Framework?

SaveChanges() always happens in a transaction which will be rolled back if an exception happens. In your case there is no need to try to handle this manually (in this particular case it would be even better to add all entities first and SaveChanges only once).


1 Answers

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();
    }
}
like image 183
Steven Avatar answered Sep 30 '22 17:09

Steven