Entity Framework Core 2.1: Data Seeding

I am taking some time to explore some of the new features that came out with the .NET Core 2.1 release and this post is going to be a continuation of that process. The following are links to the other posts in this same vein.

Host ASP.NET Core Application as a Windows Service
ASP.NET Core 2.1: ActionResult<T>

Today we are going to be looking at a new feature added to Entity Framework to allow for data seeding. I am using the official docs for this feature as a reference.

Sample Application

We are going to use the .NET CLI to create a new application using the MVC template with individual authorization since it is one of the templates that come with Entity Framework already set up. If you have an existing project and need to add Entity Framework you can check out this post. The following is the command I used to create my project.

dotnet new mvc --auth Individual

Model

Before we get to data seeding we need to create an entity to seed. In this example, we will be creating a contact entity (surprise!). In the Models directory, I created a Contacts.cs file with the following contents.

public class Contact
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

Next, in the Data directory, we are going to open the ApplicationDbContext class and add a DbSet for our new Contact entity. Added the following property to the class.

public DbSet<Contact> Contacts { get; set; }

Now that we have our DbContext setup lets add a migration for this new Contact entity using the following .NET CLI command.

dotnet ef migrations add Contacts -o Data/Migrations

Finally, run the following command to create/update the database for this application.

dotnet ef database update

Data Seeding

Now that our project is setup we can move on to actual data seeding. In Entity Framework Core data seeding is done in the OnModelCreating function of your DbContext class. In this example that is the ApplicationDbContext class. The following example shows using the new HasData method to add seed data for the Contact entity.

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.Entity<Contact>().HasData(
        new Contact 
        {
            Id = 1,
            Name = "Eric",
            Address = "100 Main St",
            City = "Hometown",
            State = "TN",
            Zip = "153789"
        }
    );
}

Data seeding is handled via migrations in Entity Framework Core, which is a big difference from previous versions. In order to get our seed data to show up, we will need to create a migration which can be done using the following command.

dotnet ef migrations add ContactSeedData -o Data/Migrations

Then apply the migration to your database using the following command.

dotnet ef database update

Looking at the code that the migration created you can see that it is just inserting the data.

public partial class ContactSeedData : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.InsertData(
            table: "Contacts",
            columns: new[] { "Id", "Address", "City", "Name", "State", "Zip" },
            values: new object[] { 1, "100 Main St", "Hometown", "Eric", "TN",
                                   "153789" });
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DeleteData(
            table: "Contacts",
            keyColumn: "Id",
            keyValue: 1);
    }
}

The above works great on new databases or new tables but can cause issues if you are trying to add seed data to an existing database. Check out Rehan’s post on Migrating to Entity Framework Core Seed Data for an option on how to deal with this.

Wrapping up

I am very happy to see that we have a way to prepopulate data in Entity Framework Core it will make some scenarios, such as mostly static data, much easier to deal with. One downside I see to the migration approach is the inability to have some built-in test data since the migrations will always be applied to your databases.


Also published on Medium.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.