Showing posts with label Entity Framework 6. Show all posts
Showing posts with label Entity Framework 6. Show all posts

Saturday, August 17, 2013

Transaction Support in Entity Framework 6





The Entity Framework team has announced the new version of Entity Framework 6 beta pro. I describe in this article series new features introduced in Entity Framework 6.
My last article was Code First Stored Procedure in Entity Framework 6. You can see this from:

Code First Insert Update and Delete Stored Procedure in Entity Framework 6 Pre

Now, through this article, I provide another new specification of Entity Framework 6. The new APIs make the developer easy to worki with transactions in Entity Framework.

Transaction: Transaction is used to ensure that everything in the unit of work is either successful or failed. 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.First we need to install the Entity Framework 6 Pre in Visual Studio 2012,
How to Install the Entity Framework 6 Beta version in .NET Framework 4.5
From the Tools menu, select "Library Package Manager" and then click "Package Manager Console".

package-manager-console-in-vs2012.jpg

To install Entity Framework, run the following command in the Package Manager Console.
PM> Install-Package Entity Framework -Pre

install-entity-framework-in-vs-2012.jpg

In Entity Framework 6 we can now add the two new APIs to DbContext.Database that makes working with transactions easier.
"UseTransaction" and "BeginTransaction"

In this article however I will only consider how to use "BeginTransaction()" to work with the transactions in Entity Framework 6.

BeginTransaction():  This method returns a "DbContextTransaction" object and will open the underlying database connection if necessary. This method has two overriden constructors. Both the overrides takes the "IsolationLevel" for the transaction.

1.  The first one is the default constructor that takes no arguments, which means it uses the default for the transaction.
2.  The second takes an explicit "IsolationLevel" for the transaction.

DbContextTransaction: It provides the two methods "Commit()" and "Rollback()" that perform Rollback and Commit on the transaction.

Now, let's start code to see how to use Transaction in Entity Framework 6.

Here, I'll use a console application in VS2012 using C#.

I am using Code First to use the Transaction. When using Code First development you usually begin by writing .NET Framework classes that define your conceptual (domain) model.

The code below defines a set of model classes. Open the Program.cs file and paste the following class definitions.



public class PostInformation
{
        [Key]
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
}

public class PostAdditionalInformation
{
        [Key]
        public int PostId { get; set; }
        [Required]
        public string PostName { get; set; }
}

To use the appropriate annotations, include the Namespaces in the file.
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;


Define the DbContext Derived Type

In addition to defining entities, you need to define a class that derives from DbContext and exposes DbSet<TEntity> properties. The DbSet<TEntity> properties.

An instance of the DbContext derived type manages the entity objects during run time, that includes populating objects with data from a database, change tracking, and persisting data to the database.

In the Program.cs add the context definition.
public partial class PostEntityContainer : DbContext
{
        public PostEntityContainer() : base("name=EntitieConnectionString")
        {
        } 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        }
        public DbSet<PostInformation> Post_Details { get; set; }
        public DbSet<PostAdditionalInformation> PostAddtional_Details { get; set; }}


Here, I will call the base constructor of the "DbContext" class by passing the Connection String key name that is defined in my "Web.Config" file.

Now, after creating the basics Entity Framework, it's time to use the following declaration in the Main method with a transaction.
Open the Program.cs file where the Main method is defined. Add the following code into the Main function.
static void Main(string[] args)
        {
            using (var context = new PostEntityContainer())
            {
                using (var dbcxtransaction = context.Database.BeginTransaction())
                {
                    try
                    {
                        PostInformation NewPost = new PostInformation()
                        {
                            PostId = 101,
                            Content = "This is my first Post related to Entity Model",
                            Title = "Transaction in EF 6 beta"
                        };
                        context.Post_Details.Add(NewPost);
                        context.SaveChanges();
                        PostAdditionalInformation PostInformation = new PostAdditionalInformation()
                        {
                            PostId = (101),
                            PostName = "Working With Transaction in Entity Model 6 Beta Version"

                        };
                        context.PostAddtional_Details.Add(PostInformation);
                        context.SaveChanges();
                        dbcxtransaction.Commit();
                        Console.WriteLine("Data Saved Successfully. Transaction Commited");
                    }
                    catch
                    {
                        dbcxtransaction.Rollback();
                        Console.WriteLine("Error Occured during data saved. Transaction Rolled Back");
                    }
                }
            }
        }

The code above will call the "SaveChanges()" method on the context two times on the different "DbSet" underlying the same transaction. If both the entities are saved successfully then the transaction will be successfully committed, otherwise it wil be rolled back.Note: Beginning a transaction requires that the underlying store connection is open. So calling BeginTransaction() will open the connection if necessary. If "DbContextTransaction" opened the connection then it will close it when "Dispose()" is called. 

Now, run the application and see what happens with it.

When you run the application, you get the following message on the screen.


transaction Commited in Entity Framework.jpg

When you open your database with a respective connection string, you will notice that the will be inserted in both of the tables.

Sql-Table-in-Sql-Server.jpg


Now, I will change some code during the second insertion of the entity to the set, so that it will go through the catch block and transaction when it is being rolled back.
static void Main(string[] args)
        {
            using (var context = new PostEntityContainer())
            {
                using (var dbcxtransaction = context.Database.BeginTransaction())
                {
                    try
                    {
                        PostInformation NewPost = new PostInformation()
                        {
                            PostId = 101,
                            Content = "This is my first Post related to Entity Model",
                            Title = "Transaction in EF 6 beta"
                        };
                        context.Post_Details.Add(NewPost);
                        context.SaveChanges();
                        PostAdditionalInformation PostInformation = new PostAdditionalInformation()
                        {
                            PostId = 101,
                        //    PostName = "Working With Transaction in Entity Model 6 Beta Version" Comment the Line, which is mark as required.
                        };
                        context.PostAddtional_Details.Add(PostInformation);
                        context.SaveChanges();
                        dbcxtransaction.Commit();
                        Console.WriteLine("Data Saved Successfully. Transaction Commited");
                    }
                    catch
                    {
                        dbcxtransaction.Rollback();
                        Console.WriteLine("Error Occured during data saved. Transaction Rolled Back");
                    }
                }
            }
        }
The code above will prompt the message that the transaction is being rolled back due to some error. This is because the "PostAdditionalInformation" class has a required element that we do not passed when saving the entity to the set. See the Comment line. This time it goes through the catch block and the transaction will be completely rolled back, even the first "SaveChanges" will succeed.

Transaction Rolled Back in Entity Framwork.jpg


Here is the result of the database tables. No entry will be made in both the tables due to the transaction being rolled back.

Blank-table-in-sqlserver.jpg

New Features of Entity Framework 6



Introduction

In this article I provide some exciting and useful features of Entity Framework 6 beta release. Currently EF 6's beta release is available. The Beta release can be downloaded from NuGet. These features will be really useful and when the final release is available you will really find them useful and more powerful than the previous versions. So without wasting time I will proceed to discussing some key features.

  1. Asynchronous pattern Support The .NET Framework 4.5 introduced the Task-Based Asynchronous Pattern that uses the async modifier and the await operator to provide asynchronous programming. This feature is now supported by EF6. So database calls that fetch a large amount of data, made through EF can be processed asynchronously. By using the asynchronous pattern we can avoid blocking the responsiveness of our application.

    Let's have at look some code snippets without and with the asynchronous pattern and how to use this pattern with EF6.

    a. Without Asynchronous Patterns
     
    privatestatic void SaveInput(string question,string answer)
    {
        using (var ctx = new AnswersContext())
        {
            ctx.Questions.Add(new Question()
            {
                Content = question,
                Answers =new List<Answer> { new Answer { Content = answer } }
            });
            ctx.SaveChanges();
        }
    }

    b. With Asynchronous Patterns
    privatestatic void PrintQuestions()
    {
        using (var ctx = new AnswersContext())
        {
            foreach (var q in ctx.Questions)
            {
                Console.WriteLine(q.Content);
                foreach (var a in q.Answers)
                {
                    Console.WriteLine(" -" + a.Content);
                }
            }
        }
    }

    As you can see, I have used async and await, two new keywords. If we are using the await operator then it is necessary to use async with the method signature. Since we are calling the ToListAsync method, as soon as this method is called, the thread won't block until the task finishes.
     
  2. Custom ConventionsWhen we use the code first approach in Entity Framework, classes are mapped with the database using a set of conventions that are defined in EF, such as which property becomes the primary key, which name of in the table maps with an entity name etcetera. We must use some custom code conventions for that. Sometimes these default conventions are not perfect for our model and we must do configuration using Data annotation and other ways.
     
  3. Code First Mapping to Insert/Update/Delete Stored Procedures When we use code first entities, it is easy to select data using Stored Procedures but there was no way to delete, update and insert data using Stored Procedures.

    EF 6 provides this ability to insert, update and delete using a Stored Procedure. So you can do that as in the following:
     
    mBuilder .Entity<Users>() .MapToStoredProcedures(s => {
    s.Update(u => u.HasName("modify_User"));
    s.Delete(d => d.HasName("delete_User"));
    s.Insert(i => i.HasName("insert_User"));
    });
     
  4. Connection ResiliencySince we know that currently most database servers are a cloud, such as an Azure Database. So the chances of connection failures are greater. This could be because of some defensive techniques used by the cloud database because of how the cloud database maintains its consistency, so to maintain that, sometimes it closes the connection explicitly.

    EF 6 provides many ways to retry actions to be performed on the database and to minimize the number of failures and the effect of defensive code. Even users can create their own retry strategies and decide which action should be performed if an exception occurs.
     
  5. Better supports of POCO entitiesNow we can make nesting of entities and complex types inside classes. We can also have Custom Equal and GetHashCode Method implementations.
     
  6. Multiple Context Per DatabaseIn EF 5, when we use Migration or a Code first database created automatically then we can have only one code first model per database. But In EF 6 , we will be able to have multiple code first models per database.
     
  7. Default Isolation levelDefault isolation level has been changed for databases created using code first in EF6. In EF 5 it was Serializable so now it has been changed to READ_COMMITTED_SNAPSHOT. So because of this isolation level the database becomes more scalable and there are very few chances of deadlock.
     
  8. Supports Enum and Spatial data types :EF 6 now provides support of Enum and Spatial Data Types.
     
  9. Now easy to set default schema at one placeEF 6 provides the DbModelBuilder.HasDefaultSchema Code first API that allows configuration of a default database schema for the code fist model in one place. Previously this default schema was hard-coded to dbo and if we needed to change it , we needed to do a lot of work.

Summary

In this article I have discussed some key features that have been introduced in the Beta release of Entity Framework 6 . There are many other features also introduced in EF 6. For more information you can refer to the following Codeplex website.