Monday, December 15, 2014

Entity Framework Code-First Migrations: Seed data using AddOrUpdate

Bottom line

By adding sample data to the Configuration.cs file in your Migrations folder, model updates can be easily administered to your database while avoiding unnecessary and time consuming errors.

The issue

If you're using migrations for your database updates, you may run into migration errors as a result of duplicate data and incorrect foreign key relationships. Utilizing the AddOrUpdate function correctly will avoid migration errors such as:
  • Sequence contains more than one element
  • The INSERT statement conflicted with the FOREIGN KEY constraint 

The code

After enabling Code-First Migrations in your project, you should see the folder Migrations with Configration.cs located inside. Configuration.cs and in the Seed method, I've added the following in order to create four records inside my Permission table:

var permissions = new List<Permission>
            {
                new Permission {Name = "Create Item", Description = "Grants user the ability to create items"},
                new Permission {Name = "Modify Item", Description = "Grants user the ability to modify items"},
                new Permission {Name = "Delete Item", Description = "Grants user the ability to delete items"},
                new Permission {Name = "Read Item", Description = "Grants user the ability to read items"},
            };
 permissions.ForEach(p => context.Permissions.AddOrUpdate(n => n.Name, p));
 context.SaveChanges();

While there are several ways to add data to your context, using List<> will surely be one of the quickest ways.

What you may have missed

Many sample solutions, Stack Overflow answers and guides fail to use the full capability of AddOrUpdate by simply not adding a identifying property to the identification expression (see bold):

itemList.ForEach(item => context.ItemDbSet.AddOrUpdate(n => n.Name, item));

In this example, the Name property on our Permission entity is used as the identification property for comparing the seed data to what already exists in the database. If an item with the same name exists, it will update the item as opposed to adding a new one. This will save your existing relationships between records and avoid most issues with migrating model updates with existing data.

The context

This is for a ASP.NET SPA running Entity Framework 6, Visual Studio 2013, Code-First, Migrations enabled, SQL Server (or LocalDb) and Web API.

Helpful links

Code First Migrations and Deployment with the Entity Framework in an ASP.NET MVC Application