如何运行配置类迁移的 Seed() 方法

Posted

技术标签:

【中文标题】如何运行配置类迁移的 Seed() 方法【英文标题】:How to run Seed() method of Configuration class of migrations 【发布时间】:2013-05-23 02:55:25 【问题描述】:

我有两个问题:

1) 如何在不更新数据库模型的情况下从包管理器控制台运行 Seed() 方法?

2) 有没有办法在代码中调用 Seed() 方法?

感谢任何建议。

【问题讨论】:

我在使用 EF6 时遇到了这个问题,然后意识到我选择了错误的默认项目,因此更新数据库没有找到要运行的配置。值得注意的是,仅在 EF6 中执行更新数据库将始终运行 Seed() 方法。我不知道这在撰写本文时是否属实。 我遇到了一个问题,即没有调用种子方法,但我正在使用“- script”修饰符运行。删除它并调用种子方法。 【参考方案1】:

如果您使用上下文初始化器作为 MigrateDatabaseToLatestVersion,配置中的种子方法应自动运行。不要认为您需要手动调用它。

【讨论】:

但是如果我想手动调用它呢?我在包管理器控制台中创建了更新数据库并运行了我的 Seed() 方法。但是我之后我做了一些删除数据库中信息的工作。所以我想独立运行更新数据库的 Seed() 方法。有什么想法吗? 一种选择是创建用于迁移的 sql 脚本。这可以通过使用 update-database -script -targetmigration: 来实现。创建脚本后,您可以在脚本末尾添加您想要的任何种子信息。这些将是 sql 插入语句。您可以在创建的迁移文件的 up 方法中运行脚本。【参考方案2】:

经过研究,我终于找到了解决此问题的方法:

1) 公开Configuration

public sealed class Configuration : DbMigrationsConfiguration<YourContextClassHere>

2) 在下面的任意位置添加代码。它将运行最新的迁移并更新您的数据库:

Configuration configuration = new Configuration();
configuration.ContextType = typeof(YourContextClassHere);
var migrator = new DbMigrator(configuration);

//This will get the SQL script which will update the DB and write it to debug
var scriptor = new MigratorScriptingDecorator(migrator);
string script = scriptor.ScriptUpdate(sourceMigration: null, targetMigration: null).ToString();
Debug.Write(script);

//This will run the migration update script and will run Seed() method
migrator.Update();

【讨论】:

这回答了问题的第二部分,但第一部分如何在不更新数据库模型的情况下从包管理器控制台运行 Seed() 方法?【参考方案3】:

回答问题 #2:将所有代码从 Seed() 方法提取到另一个类。然后从 Configuration 类的 Seed() 方法中调用它:

    protected override void Seed(DbContext ctx)
    
        new DatabaseSeed().Seed(ctx);
    

然后你可以从任何地方调用它:

    new DatabaseSeed().Seed(new DbContext());

【讨论】:

AddOrUpdate 方法是 DbContext 的一种方法,所以这不起作用。【参考方案4】:

回答您的第一个问题。通过运行 add-migration SeedOnly 创建迁移

如果有任何未决更改,清除所有生成的 Up() 和 Down() 代码

public partial class SeedOnly : DbMigration

    public override void Up()
    
    

    public override void Down()
    
    

然后您可以通过在包管理器控制台中运行 update-database -TargetMigration SeedOnly 来定位特定迁移

【讨论】:

我想这是最好的答案。赞的太少太神奇了!【参考方案5】:

回答问题1:

人们通常会通过以下任一方式解决此问题:

    对模型进行临时人为更改 切换到 DropCreateDatabaseAlways,结果是数据库经常在不需要时被删除并重新创建 手动删除数据库

参考:http://blog.oneunicorn.com/2013/05/28/database-initializer-and-migrations-seed-methods/

【讨论】:

【参考方案6】:

这不是您要找的,但是请看一下:Running Entity Framework Migrations via command line prompt 这可能会帮助您或某人忘记基于应用程序的数据库迁移,因为您可以轻松地使脚本自动运行...

【讨论】:

是的,它可能对 CI 有用。谢谢。【参考方案7】:

如果你想Update-Database --Target-Migration xxx 并且你对seed() 方法没有运行感到惊讶,你可以尝试git stash 你所有的更改,使用Update-Database 从以前的版本生成数据库(到最后运行 seed() 的修订版)然后运行 ​​git stash apply

这是一个丑陋的解决方法,但它帮助了我。

顺便说一句:不要忘记在存储之前暂存您的更改

【讨论】:

【参考方案8】:

Configuration 类中添加一个新的公共方法。新方法只调用受保护的方法Seed

public void RunSeed(DbContext db)

    Seed(db);

然后从例如调用新方法。单元测试:

var db = new SomeDbContext();
var configuration = new Configuration();
configuration.RunSeed(db);

【讨论】:

【参考方案9】:

我知道这是一个非常古老的问题,但如果有人点击这里并出于共享信息的目的:

对我来说,回答问题 1 的最简单方法是先解决问题 2,然后使用结果解决第一个问题。这就像上面回答的@leifbattermann (https://***.com/a/24413407/2996749) 或@Martin Staufcik 方法一样简单,然后只需在一些您可以随时运行的代码中调用函数/方法,具有惊人的优势:它可用于在某些情况下设置默认值,例如为新客户创建新数据库等。

别忘了,如果您使用@leifbattermann 方法并从Configuration 类以外的其他地方调用该函数并创建新的DbContext,则需要在之后调用SaveChanges()。至少对我来说,就是这样。

还有一件事:如果您没有待处理的迁移并且只想播种,只需在包管理器控制台中运行命令“update-database”即可。

【讨论】:

以上是关于如何运行配置类迁移的 Seed() 方法的主要内容,如果未能解决你的问题,请参考以下文章

找不到类“用户”

我的Seed()方法永远不会在Code First EF 5中调用

如何在 android 检测测试类中运行单个测试方法以及如何为此更改编辑配置

如何安装VMware vSphere vMotion网络配置的方法步骤

java 27 - 6 反射之 通过配置文件运行类中的方法

如何在配置类路径阶段获取有关 Grails 应用程序的更多信息?