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.
For example I have two entities, employee and department, and I have added the employee and department entities to the context object and finally call the SaveChanges() method. The Entity Framework creates a single transaction for these multiple inserts.
- using (EntitiesContext context = new EntitiesContext())
- {
- EmployeeMaster employee = new EmployeeMaster();
- employee.Code = "A0001";
- employee.Name = "Jignesh Trivedi";
- employee.DepartmentId = 1;
- context.Employees.Add(employee);
- DepartmentMaster dept = new DepartmentMaster();
- dept.Code = "DEP0001";
- dept.Name = "Department 1";
- context.Departments.Add(dept);
- context.SaveChanges();
- Console.ReadLine();
- }
Earlier the System.Transactions namespace was used to handle transactions in the Entity Framework using TransactionScope and the Entity Framework uses this transaction to save the changes in the database.
- using (TransactionScope scope = new TransactionScope())
- {
- //Code Here
- }
Entity Framework 6.0 introduced two new APIs to maintain the transaction.
- DbContext.Database.BeginTransaction: It allows us to begin a transaction. It allows us to combine several operations to be combined within the same transaction and hence all the transactions are either committed or rolled back. This method allows us to specify the isolation level for the transaction.
- DbContext.Database.UseTransaction: It allows DbContext to use a transaction that was stated outside of the Entity Framework. It means using this API we can use any existing transaction with Entity Framework.
DbContext.Database.BeginTransaction
This method returns a DbContextTransaction object. The BeginTransaction method has two overloads, one has no argument and the other accepts an explicit Isolation Level.
A DbContextTransaction object provides Commit() and Rollback() methods to do commit and rollback on the underlying store transaction.
Test Code
This method returns a DbContextTransaction object. The BeginTransaction method has two overloads, one has no argument and the other accepts an explicit Isolation Level.
A DbContextTransaction object provides Commit() and Rollback() methods to do commit and rollback on the underlying store transaction.
Test Code
- using (EntitiesContext context = new EntitiesContext())
- {
- using (var transaction = context.Database.BeginTransaction())
- {
- try
- {
- EmployeeMaster employee = new EmployeeMaster();
- employee.Code = "A0001";
- employee.Name = "Jignesh Trivedi";
- employee.DepartmentId = 1;
- context.Employees.Add(employee);
- context.SaveChanges();
- DepartmentMaster dept = new DepartmentMaster();
- dept.Code = "DEP0001";
- dept.Name = "Department 1";
- context.Departments.Add(dept);
- context.SaveChanges();
- transaction.Commit();
- }
- catch (Exception ex)
- {
- transaction.Rollback();
- }
- }
- }
The overloaded version of the DbContext.Database.BeginTransaction method:
SQL logging output
DbContext.Database.UseTransaction
Sometimes we must use an existing transaction that is started outside of the Entity Framework. In this case the DbContext.Database.UseTransaction API is very useful. In this method we can pass an existing transaction object.
To maintain the transaction, the connection object must be the same, so we are required to create a DbContext contractor that takes a connection as an argument.
- public class EntitiesContext : DbContext
- {
- public EntitiesContext()
- : base("name=Entities")
- {
- Database.Log = Console.WriteLine;
- }
- public EntitiesContext(DbConnection existingConnection, bool contextOwnsConnection)
- : base(existingConnection, contextOwnsConnection)
- {
- }
- }
- using(SqlConnection con = new SqlConnection("connectionString"))
- {
- con.Open();
- using(var transaction = con.BeginTransaction())
- {
- // Do something....
- //Pass this transaction to EF....
- using (EntitiesContext context = new EntitiesContext(con, false))
- {
- context.Database.UseTransaction(transaction);
- EmployeeMaster employee = new EmployeeMaster();
- employee.Code = "A0001";
- employee.Name = "Jignesh Trivedi";
- employee.DepartmentId = 1;
- context.Employees.Add(employee);
- context.SaveChanges();
- }
- }
- }
Excellent article and with lots of information. I really learned a lot here. Do share more like this.
ReplyDeleteBenefits Of Web Designing
Advantages Of Web Designing