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.
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.
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.
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.
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).
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With