Disable Entity Framework Code First Initialization Logic

When you use the Entity Framework Code First approach to build your database, EF’s default behavior is to verify if a database exists when the application runs the first time. In case it does not exist, EF creates it.

There might exist some situations when there is no need to run this initialization logic, e.g. when you run unit tests on an existing database.

Disabling the initialization for a given context type is really simple. This call will do the job:

System.Data.Entity.Database.SetInitializer<TContext>(null);

I found a sample on Stack Overflow where a custom System.Data.Entity.IDatabaseInitializer<TContext> was implemented, having an empty InitializeDatabase method. But why create and maintain a class when we can get the same result for free.

Setting the initializer to null should be performed before the database is accessed the first time by the context type. I prefer to put this into the initialization method of my application or inside of the TestInitialize method of my unit test classes. Putting this code into the ctor of the DbContext class will lead to an unneeded number of calls every time an instance of the context class is created.

And because I forgot to do so, an additional hint concerning the unit tests: It is not sufficient to disable the initialization logic for the DbContext type defined / used in the test project. Also, the initializer of the DbContext type used by the application classes, defined in the application project, has to be set to null.

Links

Understanding Database Initializers in Entity Framework Code First

Handle Race Conditions / Concurrency in Code First Entity Framework Applications

Preface

A common scenario in developing applications is the handling of concurrent database updates.

Given there is an application to manage customers, that is used by multiple users simultaneous.

User U1 reads the data of customer C1. While user U1 is looking at this data, user U2 reads the data of customer C1 too. Meanwhile, user U1’s phone is ringing. She picks it up. User U2 changes some of the customer’s data and saves it to the database. User U1 finishes the phone call, make some changes to the same customer, and saves it too.

Without handling the race condition or concurrency, al changes made by user U2 will be lost in this example. Handling it, the application should not save the changes made by user U1 and inform her that the customer’s data was changed in the meantime by another user.

In this post I will show an approach and sample code on how an application using the Entity Framework and the Code First approach can handle this.

Code Preparation

There is only one step required to make Entity Frame do all the work for you: Define a Version property in the model class (the name of the property does not matter at all), and decorate it with a Timestamp attribute.

/// <summary>
/// This column will be used by EF for race condition validation.
/// </summary>
[Timestamp]
public byte[] Version { get; set; }

Believe it or not – this is all you have to do (in case you are using the Code First approach).

Entity Framework will set the Version property to a value when the record is inserted into the database. Every time EF updates the record, it verifies that the value of the column has not changed. Doing an update, the version is increased.

Handling a Race Condition

EF throws a DbUpdateConcurrencyException in case a record was changed since the data was read.

So you have to catch this exception whenever your application updates or deletes database records and inform the user that the data was changed. In case there is no user to be informed, e.g. if this happens in a background process, you have to implement an appropriate error handling mechanism.

Using the Sample

To see EF Concurrency Handling in action, you can use the sample application.

There are two “clients” implemented, accessing both the same database record. Take these steps to provoke a concurrency exception:

  • Read the record for client 1 (press the Read Record button of the Client 1 group)
  • Read the record for client 2 (press the Read Record button of the Client 2 group)
  • Update the record for client 2 (press the Update Record button of the Client 2 group)
  • Try to update the record for client 1 (press the Update Record button of the Client 1 group)

The result should look like this:

Sample when Race Condition occurred

Some Sample Details

The sample code was created using Visual Studio 2013 Ultimate and Entity Framework 6.1. In case you use an older version of Visual Studio, you might have to create an empty solution and add the files to it.

The application expects a SQL Server instance (not SQL Server Express) installed on the local machine having the default server name (MSSQLSERVER). In case you do not have a SQL Server with this name running on your machine, you have to change the connection string in the app.config file before you can run the sample.

On the SQL Server, the application creates a database named EntityFrameworkRaceCondition. Please make sure to have the appropriate rights to create a database when you run the sample.

Links

Microsoft Data Developer Center Entity Framework

Entity Framework / Get Started / Code First to a New Database

Entity Framework Tutorial Update Entity Using DbContext

Wikipedia Race Condition

Sample Application