如何使用新生成的数据库添加新的代码优先迁移?

2023-12-19

我已经在实体框架项目上启用了代码优先迁移,并添加了几个迁移来执行重命名表之类的操作。但是,我现在已经删除了数据库,并使实体框架根据我最新的数据模型生成一个全新的数据库。如果我尝试运行:

PM> Add-Migration TestMigration

...它告诉我,我需要首先应用现有的迁移。所以我跑:

PM> Update-Database

...但问题是它正在尝试更新不需要更新的数据库;它已经基于最新的数据模型。因此,当它尝试重命名现在不存在的表时,我收到错误。

有什么方法可以向数据迁移表明我的数据库是最新的并且不需要在其上运行任何迁移?我应该怎么办?


我找到了一种方法来表明我的数据库是最新的,并且它(毫不奇怪)基于修改__MigrationHistory表,代码优先迁移用于确定运行时将哪些迁移应用于数据库Update-Database.

顺便说一句,在研究这个答案时,我发现了一个关于代码优先迁移命令的非常好的参考,可以在以下位置找到:http://dotnet.dzone.com/articles/ef-migrations-command http://dotnet.dzone.com/articles/ef-migrations-command

当 EF 自动从头开始创建数据库时,它始终会将单个条目放入__MigrationHistory表,该条目将具有 MigrationId(currentDateTime)_InitialCreate。这代表EF刚刚进行了数据库的初始创建。但是,您的迁移历史记录不会以该 MigrationId 开始,因为您将从其他内容开始。

要“愚弄”代码优先迁移,让其认为您正在进行最新迁移,您需要删除该迁移(currentDateTime)_InitialCreate条目来自__MigrationHistory新创建的数据库的表,并插入如果您仍然拥有已应用迁移的旧数据库的话本应存在的内容。

因此,首先删除新生成的数据库中的所有内容__MigrationHistory桌子。然后,进入包管理器控制台并运行:

PM> Update-Database -Script

从生成的 SQL 脚本中,取出以以下内容开头的所有行:

INSERT INTO [__MigrationHistory]...

然后,运行那些INSERT新创建的数据库上下文中的语句。检查这些行中的每一行现在都存在于您的__MigrationHistory桌子。当您下次运行时:

PM> Update-Database

...您应该收到一条消息“没有待处理的基于代码的迁移”。恭喜 - 您已经欺骗了代码优先迁移,让其认为您现在正在进行最新的迁移,并且您可以从此处继续添加新迁移。

我确实认为应该有一些自动化的方法来内置到 EF 代码优先中,但是......也许他们应该添加类似的内容:

PM> Update-Database -MigrationsTableOnly

...它将破坏迁移表中的现有条目,并且只是将新条目插入到项目中定义的每个迁移的迁移历史记录中,但实际上并不尝试运行迁移。呃,好吧。

UPDATE
我找到了一种很好地自动化此操作的方法,即使用自定义初始化程序的 Seed 方法。基本上,种子方法会在创建数据库时删除现有的迁移历史数据,并插入您的迁移历史记录。在我的数据库上下文构造函数中,我注册自定义初始值设定项,如下所示:

public class MyDatabaseContext : DbContext {
    public MyDatabaseContext() : base() {
        Database.SetInitializer(new MyDatabaseContextMigrationHistoryInitializer());
    }

自定义初始化程序本身如下所示:

/// <summary>
/// This initializer clears the __MigrationHistory table contents created by EF code-first when it first
/// generates the database, and inserts all the migration history entries for migrations that have been
/// created in this project, indicating to EF code-first data migrations that the database is
/// "up-to-date" and that no migrations need to be run when "Update-Database" is run, because we're
/// already at the latest schema by virtue of the fact that the database has just been created from
/// scratch using the latest schema.
/// 
/// The Seed method needs to be updated each time a new migration is added with "Add-Migration".  In
/// the package manager console, run "Update-Database -Script", and in the SQL script which is generated,
/// find the INSERT statement that inserts the row for that new migration into the __MigrationHistory
/// table.  Add that INSERT statement as a new "ExecuteSqlCommand" to the end of the Seed method.
/// </summary>
public class MyDatabaseContextMigrationHistoryInitializer : CreateDatabaseIfNotExists<MyDatabaseContext> {
    /// <summary>
    /// Sets up this context's migration history with the entries for all migrations that have been created in this project.
    /// </summary>
    /// <param name="context">The context of the database in which the seed code is to be executed.</param>
    protected override void Seed(MyDatabaseContext context) {
        // Delete existing content from migration history table, and insert our project's migrations
        context.Database.ExecuteSqlCommand("DELETE FROM __MigrationHistory");
        context.Database.ExecuteSqlCommand("INSERT INTO __MigrationHistory (MigrationId, Model, ProductVersion) VALUES ('201210091606260_InitialCreate', 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF54AD7E074A..., '5.0.0.net40')");
        context.Database.ExecuteSqlCommand("INSERT INTO __MigrationHistory (MigrationId, Model, ProductVersion) VALUES ('201210102218467_MakeConceptUserIdNullable', 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4..., '5.0.0.net40')");
        context.Database.ExecuteSqlCommand("INSERT INTO __MigrationHistory (MigrationId, Model, ProductVersion) VALUES ('201210231418163_ChangeDateTimesToDateTimeOffsets', 0x1F8B0800000000000400ECBD07601C499625262F6D..., '5.0.0.net40')");
        context.Database.ExecuteSqlCommand("INSERT INTO __MigrationHistory (MigrationId, Model, ProductVersion) VALUES ('201210251833252_AddConfigSettings', 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF54AD7E..., '5.0.0.net40')");
        context.Database.ExecuteSqlCommand("INSERT INTO __MigrationHistory (MigrationId, Model, ProductVersion) VALUES ('201210260822485_RenamingOfSomeEntities', 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF5..., '5.0.0.net40')");
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用新生成的数据库添加新的代码优先迁移? 的相关文章

随机推荐

  • Haskell 程序中比其他语言更容易出现哪些错误?

    备受推崇的功能之一是 如果一个程序可以编译 那么它很可能大部分都是正确的 比用不太复杂或严格的类型系统的语言编写的程序更是如此 也就是说 Haskell 是一个将运行时错误转换为编译器错误的系统 我想知道 用 Haskell 编程是否会出现
  • Flutter - 有状态小部件在切换选项卡时不会保存计数器状态

    我正在学习 flutter 正在使用 tabBars 但在保存状态时遇到问题 我在下面列出了我的问题的一个小工作示例 基本上 有一个按钮和一个状态计数器 当我单击按钮时 我看到文本字段正确更新 但是 当我切换到不同的选项卡并返回时 文本字段
  • 修改HAProxy Lua库路径

    我正在尝试从 HAProxy 加载 Lua 脚本 在 Lua 脚本中 以下行导致错误 local http require socket http 最初我收集自journalctl xe输出表明该库未安装 我安装它使用luarocks in
  • 如何使用tensorflow进行k折交叉验证?

    我正在关注张量流的 IRIS 示例 https github com tensorflow tensorflow tree master tensorflow examples tutorials monitors 我现在的情况是 我将所有
  • 用于开始 Java 源文件的有效关键字

    到目前为止 我知道这些关键字对于开始 java 源文件是有效的 class public import package interface and final 评论补充 abstract strictfp enum 还有吗 感谢所有超级快速
  • 如何在 R 中编写最大似然例程?

    我想对我创建的数据样本运行一些最大似然代码 这是我到目前为止所拥有的 library maxLik data lt replicate 20 rnorm 100 logLikFun lt function param mu lt param
  • 同步数据库 Mysql SQLite [重复]

    这个问题在这里已经有答案了 可能的重复 如何将Android手机上的SQLite数据库与服务器上的MySQL数据库同步 https stackoverflow com questions 6511402 how to sync sqlite
  • Flutter 使用分享意图在 YouTube 上分享视频

    When press on share button It opens the sharing dialog box as shown below When press on youtube it share video on youtub
  • 使用 PHP 脚本发送和接收短信?

    Can a PHP脚本 可以与 MySQL 数据库一起使用 发送和 或接收短信使用某种服务器端解决方案 任何特殊的服务器端应用 或特殊的hardware必需的 以及兼容性 视窗 Linux 像这样的公司还有很多Esendex http ww
  • python 相当于 PHP $_SERVER 是什么?

    我找不到与 PHP SERVER 等效的 python 有没有 或者说 有哪些方法可以带来同等的结果 提前致谢 Using mod wsgi 我会推荐它而不是 mod python 说来话长 但相信我 你的应用程序通过了环境变量例如 def
  • 如何设置 MySQL 进程或线程的最大数量?

    ps axuw grep mysql仅指示 MySQL 进程 但如果我运行 htop 我可以看到 10 行 每一行都有一个单独的 PID 所以我想知道它们是否是由于某种原因我无法使用 ps 看到的线程或进程 在我的开发机器上尝试将它们限制为
  • 访问 DOM Webkit Objective C

    熟悉 webkit 的人能否解释一下或为我指出正确的方向 为什么以下代码不起作用 我想做的是加载一个页面 让 webkit 解析它并简单地打印出标题 这是我所得到的 include
  • ViewPager 中 Fragment 上的 Fragment 不会在方向更改时重新加载

    我正在开发一个使用 ActionBarSherlock 和 ViewPagerIndicator 的 Android 应用程序 主要活动是 SherlockFragmentActivity 用户通过操作栏上的选项卡在片段之间导航 所有选项卡
  • 在 C++ 中从 AVFrame (FFMPEG) 中提取 RGB 值

    我目前正在尝试使用 FFMPEG 读取视频帧 格式为PIX FMT RGB24 对于每个帧 RGB 值都在frame gt data 0 中组合在一起 其中帧的类型为 AVFrame 如何提取每帧的单独 R G 和 B 值 这是为了处理视频
  • 根据另一列中的值删除一列的重复项、Python、Pandas

    我有一个像这样的数据框 Date PlumeO Distance 2014 08 13 13 48 00 754 447905 5 844577 2014 08 13 13 48 00 754 447905 6 888653 2014 08
  • 使用 ORDER BY 和 LIMIT 进行更新在 MYSQL 中不起作用

    我是 MYSQL 的新手 无法解决 甚至在这个论坛上有这么多答案 也无法识别此语句中的错误 我使用的是MYSQL数据库 我有 2 个表 Ratemaster 和 rates 其中客户可以拥有 1 个具有不同费率的产品 因此 客户和产品字段会
  • 本机查询插入后如何在 JPA 中获取返回 ID

    我在 JPA 中有以下代码 用于在使用本机查询插入后返回自动生成的 ID Query q em createNativeQuery insert into returning ID Long class q executeUpdate 但是
  • Ghostscript PDF 到 PNG:输出始终为 595x842 (A4)

    我尝试将 PDF 转换为 PNG 但输出图像始终是 A4 但源 PDF 非常大 这是我的命令 dNOPAUSE dBATCH dSAFER sDEVICE png16m dFirstPage 1 sOutputFile D PDF png
  • 我可以从 NSHTTPURLResponse 中的 HTTP 状态行访问“原因短语”吗

    指定 HTTP 的 RFC 2616 在第 6 1 1 节中表示 状态行的部分是 3 位数字状态代码和文本 原因短语 我正在构建一个 iPhone 应用程序 它使用 NSURLConnection 通过 HTTP 访问数据 我可以毫无问题地
  • 如何使用新生成的数据库添加新的代码优先迁移?

    我已经在实体框架项目上启用了代码优先迁移 并添加了几个迁移来执行重命名表之类的操作 但是 我现在已经删除了数据库 并使实体框架根据我最新的数据模型生成一个全新的数据库 如果我尝试运行 PM gt Add Migration TestMigr