首页 文章

实体框架:多代码优先迁移和配置种子方法

提问于
浏览
1

我正在使用Entity Framework Code First Migrations向表中添加一列 . 我已经读过你可以在configuration.cs中使用Seed方法,它会在运行update-database时播种数据 . 如果您有多次迁移,这如何工作?一次迁移可能需要为某些数据设定种子,另一次迁移可能需要其他种子数据 . 配置文件中只有一个Seed方法 . 当您添加更多迁移时,如何防止Entity Framework将来多次播种相同的数据?您是否只删除配置文件中Seed方法的内容?

3 回答

  • 2

    运行 Update-Database 时,Seed方法将作为参数传递 DbContext . 您可以使用上下文执行任何操作,包括查询数据库以查看已存在的数据并确保Seed方法是幂等的 .

    例如,如果不存在,您可能希望始终确保数据库始终与管理员一起播种...

    protected override void Seed(MyDbContext context)
    {
        if (!context.Users.Any(u => u.Username == "administrator"))
        {
            var user = new User { Username = "administrator", PasswordHash = "hashed password" };
            context.Users.Add(user);
            context.SaveChanges();
        }
    }
    
  • 2

    我在我的数据库中存储 currentVersion 的变量,并将其与新版本进行比较并执行升级操作 . 它的作用类似于以下代码 . 如果 currenVersion 早于 newVersionUpgradeVersion() 将执行升级操作 . 如果 currentVersion 等于或高于 newVersionUpgradeVersion() 什么也不做 .

    protected override void Seed(MyDbContext context)
        {
            //  This method will be called after migrating to the latest version.
    
            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data. E.g.
            //
            //    context.People.AddOrUpdate(
            //      p => p.FullName,
            //      new Person { FullName = "Andrew Peters" },
            //      new Person { FullName = "Brice Lambson" },
            //      new Person { FullName = "Rowan Miller" }
            //    );
            //
    
            UpgradeVersion(context, 100, null);
            UpgradeVersion(context, 101, (ver) => { /*do upgrade actions to version 101 */ });
            UpgradeVersion(context, 102, (ver) => { /*do upgrade actions to version 102 */ });
        }
    
        private void UpgradeVersion(MyDbContext context, int newVersion, Action<int> upgradeAction) {
            //  If newVersion > currentVersion, call upgradeAction(newVersion) and set currentVersion to newVersion
            //  Else, return directly and do nothing.
    
        }
    
  • 1

    我知道这有点晚了,但我遇到了这个答案并对此不满意 . 经过一些修补,这是另一种解决方案 .

    运行以下命令:

    add-migration YourSchemaMigration
    update-database
    add-migration YourDataMigration
    

    这应该支持并应用您的架构更改,然后第二个添加迁移调用应该为您构建一个空迁移 . 不使用迁移来添加或删除字段或表,而是在那里打开DbContext并开始删除数据

    public partial class YourDataMigration : DbMigration 
    {
        public override void Up() 
        {
            // Importing from CSV
            using(db = new FooDbContext())
                ImportUtil.ImportFoos(db, "initial_foo_data.csv"));
        }
    
        public override void Down()
        {
            // Nothing!
        }
    
    }
    

相关问题