MigrateDatabaseToLatestVersion没有运行的Seed()方法

时间:2016-03-15 23:50:51

标签: c# entity-framework ef-migrations

我尝试自动生成数据库(如果它不存在)并运行Seed()方法来填充数据。在我的数据库上下文构造函数中,我有:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDBContext, Configuration>());

这很好用,我的数据库会根据需要自动创建所有表,但似乎没有调用Seed()方法,我的数据库是空的。这是我的班级:

internal sealed class Configuration : DbMigrationsConfiguration<Context.MyDBContext>
{

    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }

    protected override void Seed(Context.MyDBContext context)
    {
        context.Users.AddOrUpdate(
            new Entities.User() { Email = "default@default.com", Password = "", Language = "en", CreatedDate = DateTime.Now }
        );

        base.Seed(context);
    }
}

当我在Update-Database控制台中运行Nuget时,数据会在数据库创建后填充,但使用MigrateDatabaseToLatestVersion时,不会调用Seed()方法。

会发生什么?我尝试从here

手动运行迁移
var configuration = new MyDbContextConfiguration();
configuration.TargetDatabase = new DbConnectionInfo(
    database.ConnectionString, database.ProviderName);

var migrator = new DbMigrator(configuration);
migrator.Update();

但也不起作用。

修改

好的,经过一些测试后,我发现Seed()方法只在数据库已经存在时运行,也就是说,在首次创建数据库时第一次运行Seed()方法没有执行,但是当我第二次运行我的应用程序时Seed()被执行了。我还必须添加context.SaveChanges()才能使其正常工作(感谢评论中的@DavidG):

protected override void Seed(Context.MyDBContext context)
    {
        context.Users.AddOrUpdate(
            new Entities.User() { Email = "default@default.com", Password = "", Language = "en", CreatedDate = DateTime.Now }
        );

        context.SaveChanges();
        base.Seed(context);
    }

所以也许我可以在Seed()内手动调用Configuration()并进行一些检查以避免添加重复数据或修改已存在的数据。

1 个答案:

答案 0 :(得分:7)

我最终得到了这个Configuration课程:

public class Configuration : DbMigrationsConfiguration<Context.MyDBContext>
    {
        private readonly bool _pendingMigrations;

        public Configuration()
        {
            AutomaticMigrationsEnabled = true;

            // Check if there are migrations pending to run, this can happen if database doesn't exists or if there was any
            //  change in the schema
            var migrator = new DbMigrator(this);
            _pendingMigrations = migrator.GetPendingMigrations().Any();

            // If there are pending migrations run migrator.Update() to create/update the database then run the Seed() method to populate
            //  the data if necessary
            if (_pendingMigrations)
            {
                migrator.Update();
                Seed(new Context.MyDBContext());
            }
        }

        protected override void Seed(Context.MyDBContext context)
        {
            // Microsoft comment says "This method will be called after migrating to the latest version."
            // However my testing shows that it is called every time the software starts

            // Run whatever you like here

            // Apply changes to database
            context.SaveChanges();
            base.Seed(context);
        }
    }

因此,通过这种方式,在创建数据库时以及有待迁移时调用Seed()方法。

这是我的MyDBContext课程:

public class MyDBContext: DbContext
{
    public MyDBContext() : base(AppSettings.DBConnectionString)
    {
    }

    public static MyDBContext Create()
    {
        return new MyDBContext();
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Entries> Entries { get; set; }
}