Saturday, November 7, 2015

Working with transaction in Entity Framework 6

In  any Relation database, maintaining the integrity of the database is very important and Transaction is one way of maintaining database integrity. When you have the situation, where you need to insert data into multiple tables and if inserting a data in one of the table fails you should always rollback other inserts transaction becomes very useful. The Same scenario can occur 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 ORM in Microsoft.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 SaveChanges() method. So all Inserts, update operation under single save changes method call will be in a single transaction. But when you want to wrap multiple SaveChanges() method under single transaction there was not inbuilt functionality in the earlier version of Entity framework. We have used to use TransactionScope class for the same.

But now with Entity Framework 6.0, We have two inbuilt APIs for Transaction.

DbContext.Database.BeginTransaction:

It allows us to Begin transaction for multiple save changes, You can combine as many operations as you want under the single transaction and hence either all will be performed successfully then the transaction will be committed  and if any exception occurred than transaction will be rollback.

DbContext.Database.UseTransaction :

Sometimes we need to use a transaction which is started outside of the entity framework. In this case, this option allows us to use that transaction with entity framework also.

In this blog post, We are going to use Begin Transaction. I will write a separate blog post about how to use existing transaction with entity framework.

So enough theory, let's create a console application understand it better.

ef6-with-transactions-console-application

We need entity framework. So I have added it via NuGet package.

entity-framework-transaction-nuget-package

In this application, we are going to use two model classes category and product. We will save them both in the single transaction and try to understand how the transaction works with Entity Framework.
namespace EFWithTransactions
{
    public class Category
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
    }
}
And here is 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 category id there in product and a product is belong to category and I have created my DB context class like following.
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; }
    }
}

And following code is for Main method of console application, Which illustrate real times scenario where 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 see above code carefully, you can see I have two save changes method one for category and another for the product. Also, I have used BeginTransaction method to initiate a new transaction. I have put one custom exception to illustrate something is wrong with that transaction. Also, try catch block is there so if any exception occurs catch block will rollback the transaction. If all went well it will commit the transaction.

Now let's run this application and following is an output as expected. As we have thrown an exception.

Transaction-roll-back-entity-framework

And there is no data inserted in database also.

sql-server-database-with-no-data

Now let's comment the throw new exception part.
//throw new Exception("Custom Exception");

And now let's run our application again and here is the output as expected.

transaction-committed-sql-server

And now we have data in the database there.

sql-server-database-with-data-transaction-commited

So now we have a really good way to use transaction in entity framework. Hope you like it. Stay tuned for more!.
You can find complete source code of above blog post on github at - https://github.com/dotnetjalps/EF6WithTransaction
Share:

0 comments:

Post a Comment

Your feedback is very important to me. Please provide your feedback via putting comments.

About Me
My Photo

Full Stack Developer,Blogger,Microsoft Mvp, Mentor, Life long learner, 10+ Years of Experience for JavaScript, web and Microsoft technologies. ASP.NET MVC,Web Forms,C#,AngularJs,Golang
Mvp profile
Subscribe to my blog

Enter your email address:

Follow us on facebook
Blog Archive
Total Pageviews