Alex Rivera | Logout

Code First Migrations and initialization error

Asked 2012-07-26T15:32:15.453
26

I'm unsure about how to use the code first migration feature. In my understanding it should create my database if it's not existing already, and update it to the latest schema according to migration files. But I'm struggling with it, because I always get a lot of errors and I'm unsure overall how to use this properly..

internal class Program
{
    private static void Main()
    {
        EntityFrameworkProfiler.Initialize();

        Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Migrations.Configuration>());

        using (var context = new MyContext())
        {
            var exists = context.Database.Exists();
            if (!exists)
            {
                context.Database.Create();
            }

            var element = context.Dummies.FirstOrDefault();
        }
    }
}

public class MyContext : DbContext
{
    public MyContext()
        : base(string.Format(@"DataSource=""{0}""", @"C:\Users\user\Desktop\MyContext.sdf"))
    {
    }

    public DbSet<Dummy> Dummies { get; set; }
}

internal sealed class Configuration : DbMigrationsConfiguration<MyContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }

    protected override void Seed(CodeFirstTest.MyContext context)
    {
    }
}

Using the Entity Framework Profiler I check what statements are executed. When I run the program with no database existing I get the following output:

-- statement #1 SELECT [GroupBy1].[A1] AS [C1] FROM (SELECT COUNT(1) AS [A1] FROM [__MigrationHistory] AS [Extent1]) AS [GroupBy1]

-- statement #2 WARN: System.Data.SqlServerCe.SqlCeException (0x80004005): The specified table does not exist. [ __MigrationHistory ] at System.Data.SqlServerCe.SqlCeCommand.ProcessResults(Int32 hr) at System.Data.

Edit
Report

1 Answer

12

It seems there are a lot of ways to configure entityframework and everyone has there own take on what is best. All I can offer is my take based on what we've standardized at my work. A lot of this is developer preference. My preference happens to be controlling as much as possible so I always understand exactly what is happening and when.

Automatic Migrations

First off, while Automatic Migrations may be convenient but they cause a lot of trouble particularly as a project grows and/or data becomes more complex. In my opinion any commercial/production system should have more control than this. We always turn off automatic migrations for all of our major projects by setting AutomaticMigrationsEnabled = false;. We run our migrations explicitly when we want it done (on dev this is in the package manager console in visual studio by typing Update-Database and in production we have written our own little migration utility that just calls the migrate to latest code explicitly - but none are automatic).

@Terric's answer scares me with both automatic migrations AND data loss being permitted! I don't want to be the guy who deploys a solution and wipes out some important data because of a badly executed column alteration that resulted in data loss. As a side note when we run out migration explicitly in dev I often use the -v switch for verbose ouptut (Update-Database -v). This lets you see the SQL being executed and any failures/warnings if appropriate.

It has also been our experience that changing these settings after you are several migrations into development doesn't go well. I'm not sure where this is being tracked, but starting a project fresh with automatic migrations disabled ensures nothing unexpected is going to happen.

Personally, I'd remove the Initializer you have MigrateDatabaseToLatestVersion and run the migrator myself exactly when I want to (either via the package man

answered 2012-08-10T17:50:54.407

Your Answer