Working with Transactions in Entity Framework 6
Jalpesh Vadgama provides a summary of using transactions with Entity Framework 6 and how, when used properly, you can keep your database clean.
Join the DZone community and get the full member experience.
Join For FreeIn any relational database, maintaining integrity of the database is very important and a Transaction is one way of maintaining database integrity. When you have a situation where you need to insert data into multiple tables and if inserting data in one of the table fails, you should always rollback other insert transactions. The same scenario exists for update or delete operations. If transactions are not there you will end up with lots of junk data in tables. Entity Framework is one of most popular ORMs in the .NET World. So in this post we are going to learn how we can use transactions with Entity Framework 6.
Transaction and Entity Framework 6
Entity Framework internally maintains a transaction when you call the SaveChanges() method. So all Inserts, update operations under a single save changes method call will be in a single transaction. But when you want to wrap multiple SaveChanges() methods under a single transaction there is not any built-in functionality in earlier versions of Entity Framework.
Now, with Entity Framework 6.0, we have two built-in APIs for transactions:
DbContext.Database.BeginTransaction
This API call will allow us to begin a transaction for multiple save changes. You can combine as many operations as you want under a single transaction and hence either all will be performed successfully then the transaction will be committed. If any exception occurs then the transaction will be rolled back.
DbContext.Database.UseTransaction
Some times we need to use a transaction which is started outside of the entity framework. In this case this API call allows us to also use that transaction with Entity Framework.
In this blog post, we are going to use Begin Transaction. In the future, I plan to write a separate blog post about how to use existing transaction with entity framework.
So enough theory, let's create a console application to understand it better.
We need Entity Framework. So I have added it via nuget package.
In this application, we are going to use two model classes called category and product. We will save them both in single transaction and try to understand how transaction works with Entity Framework.
The category model is listed below:
namespace EFWithTransactions
{
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
}
}
Here is the product model:
using System.ComponentModel.DataAnnotations.Schema;
namespace EFWithTransactions
{
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
[ForeignKey("Category")]
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
}
}
Here you can see I have the category ID in Product an Product belongs to Category. I have created my dbcontext class as shown below:
using System.Data.Entity;
namespace EFWithTransactions
{
public class ProductDbContext : DbContext
{
public ProductDbContext()
: base("ProductConnectionString")
{
}
public DbSet<Category> Categories { get; set; }
public DbSet<Product> Products { get; set; }
}
}
The Main method of console application is displayed below, which illustrates a real scenario where an exception might occurs during multiple save changes().
using System;
namespace EFWithTransactions
{
class Program
{
static void Main(string[] args)
{
using (ProductDbContext productDbContext = new ProductDbContext())
{
using (var transaction = productDbContext.Database.BeginTransaction())
{
try
{
//saving category
Category category = new Category
{
CategoryName = "Clothes"
};
productDbContext.Categories.Add(category);
productDbContext.SaveChanges();
// Throw some error to check transaction
// Comment this to make transactions sucessfull
// throw new Exception("Custom Exception");
//saving product
Product product = new Product
{
ProductName = "Blue Denim Shirt",
CategoryId = category.CategoryId
};
productDbContext.Products.Add(product);
productDbContext.SaveChanges();
Console.Write("Cateogry and Product both saved");
transaction.Commit();
}
catch (Exception exception)
{
transaction.Rollback();
Console.WriteLine("Transaction Roll backed due to some exception");
}
}
}
Console.ReadKey();
}
}
}
If you review the above code carefully, you can see I have two save changes methods: one for Category and another for Product. I have also used a BeginTransaction method to initiate a new transaction.
I have added one custom exception to illustrate something is wrong with that transaction. Also a try/catch block exists to handle any exceptions and will rollback the transaction. If all goes well it will commit the transaction.
Now let's run this application and the follow is the expected output, since we have thrown an exception.
As a result, no data has been inserted into the database.
Now let's comment the new part that throws an exception.
//throw new Exception("Custom Exception");
When we run our application again, the expected output is returned.
Now we have data in the database.
As a result, we have a really good way to use Transaction in Entity Framework. Hope you like it.
Stay tuned for more!
Published at DZone with permission of Jalpesh Vadgama, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Tactics and Strategies on Software Development: How To Reach Successful Software [Video]
-
How to Implement Istio in Multicloud and Multicluster
-
A Complete Guide to Agile Software Development
-
A Comprehensive Guide To Testing and Debugging AWS Lambda Functions
Comments