Seed your Data / 10.12.16

Entity Framework provides great tools for updating your database's schema, with auto-generated codefiles based on your classes, but when it comes to putting actual data into your fresh database, it provides you with only the bare minimum;

protected override void Seed(YourContext context)
{
    // Seed your data here
}

And that's it. So here are some practices that I try to follow.

Separate your seed data

I find there are generally two types of data I'm seeding into a fresh database. the data I want present in every instance of your database; for example tables containing a semi-static set of information, say to power dropdown boxes - lookup data. The other is test data that will only exist on developer instances or perhaps in a testing environment.

So now we might have something like this.

protected override void Seed(YourContext context)
{
    // Seed your lookup data here

    #if DEBUG
    // Your test data here
    #endif
}

So how do we actually go about adding the data?

Use DataSeed

I've built a pretty easy-to-use library to assist with this common task. It's modeled loosely off of the Schema migrations provided by EntityFramework. What DataSeed does is help you to structure and order your 'seeds', and also transactionalizes the process so if any seed fails, no changes will be made to your database.

protected override void Seed(MyDbContext context)
{
    this.Execute(context, new [] {
        // Add lookup data
        new ListOfStates(),
        ...

        #if DEBUG
        new ListOfSampleEmployees(),
        ...
        #endif
    });
}

Execute is an extension method which accept 'Seeds'. Next lets create a simple seed.

internal class ListOfStates : Seed<DataSeedTestContext>
{
    public override void Apply(DataSeedTestContext db)
    {
        // TODO: Open 'myStateSource', can be CSV, JSON, 
        // XML, or a web service call, etc.

        // Add list of states to your database
        foreach (var state in myStateSource)
        {
            // AddOrUpdate is provided in the System.Data.Entity.Migrations namespace
            db.States.AddOrUpdate(new State 
            {
                Name         = state.Name,
                Abbreviation = state.Abbreviation
            });
        }
    }
}

Now the next time you run 'update-database' your database will be filled with all the lookup data you need. And the next time another developer pulls down the code and inits their database they, too, will get all this lovely test & lookup data without having to restore any bak files or run any SQL scripts manually.

You can follow the setup guide, and follow the progress of the project here.