gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 11:17:14 25 4
gpt4 key购买 nike

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

PM> Add-Migration TestMigration

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

PM> Update-Database

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

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

最佳答案

我找到了一种方法来指示我的数据库是最新的,并且它(不出所料)基于修改 __MigrationHistory 表,代码优先迁移使用该表来确定哪些迁移在运行 Update-Database 时应用于数据库。

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

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

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

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

PM> Update-Database -Script

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

INSERT INTO [__MigrationHistory]...

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

PM> Update-Database

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

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

PM> Update-Database -MigrationsTableOnly

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

更新
我找到了一种很好地自动执行此操作的方法,即使用自定义初始化程序的 Seed 方法。基本上,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')");
}
}

关于sql-server - 如何使用新生成的数据库添加新的代码优先迁移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13103349/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com