gpt4 book ai didi

c# - 在模型更改时更新数据库架构而不会丢失数据

转载 作者:行者123 更新时间:2023-11-30 14:15:45 25 4
gpt4 key购买 nike

背景 :假设我正在使用 Entity Framework ,并且映射的实体之一如下:

class Foo
{
public int ID { get; set; }
public string Bar { get; set; }
// other useful properties
}

使用映射:
class FooMap : EntityTypeConfiguration<Foo>
{
// bear me with, I know this is redundant right now
ToTable("Foo");
HasKey(e => e.ID);
Property(e => e.ID).HasColumnName("ID");
Property(e => e.Bar);
}

在 future 的某个地方,我们需要更改 Foo 的列名因为我的老板告诉我 Foo需要一个比 ID更奢侈的名字否则我们的客户会不高兴。他告诉我们也将其重命名为“FooID”:
class FooMap : EntityTypeConfiguration<Foo>
{
// bear me with, I know this is redundant right now
ToTable("Foo");
HasKey(e => e.ID);
Property(e => e.ID).HasColumnName("FooID"); // Now you map to FooID
Property(e => e.Bar);
}

就目前而言,如果我运行它,什么都不会改变。 Foo表仍然会有一个名为 ID 的列它会抛出一个异常,告诉我列 FooID不存在。

问题 : 如何让 Entity Framework 识别我现在希望更新 Foo表使名为 ID 的列现已命名 FooID ?

更一般地说,如何让 Entity Framework 在不破坏现有数据的情况下自动将更改从我的代码传播到实际数据库中(比如在应用程序启动时)?

我不能只是“删除并重新创建”数据库,因为出于这个问题范围之外的原因,数据库在其中存储了一些其他数据,这些数据不是通过我的代码中映射的模型创建的。删除它会导致我们丢失不能使用这种机制重新创建的表。

最佳答案

如何从 Entity Framework 的噩梦中恢复 - 数据库已经有同名的表

说明 :如果您的团队刚接触 EF 时和我们一样,您最终将处于无法创建新的本地数据库或无法将更新应用到生产数据库的状态。您想回到一个干净的 EF 环境,然后坚持基础知识,但您不能。如果你让它在生产环境中工作,你就不能创建本地数据库,如果你让它在本地工作,你的生产服务器就会不同步。最后,您不想删除任何生产服务器数据。

症状 : 不能运行 更新-数据库因为它正在尝试运行创建脚本并且数据库已经有同名的表。

Error Message: System.Data.SqlClient.SqlException (0x80131904): There is already an object named '' in the database.



问题背景 :EF 根据数据库中名为 dbo.__MigrationHistory 的表了解当前数据库所在位置与代码所在位置的比较。当它查看迁移脚本时,它会尝试使用脚本来协调它上次到达的位置。如果不能,它只会尝试按顺序应用它们。这意味着,它返回到初始创建脚本,如果您查看 UP 命令的第一部分,它将是发生错误的表的 CreeateTable。

要更详细地了解这一点,我建议您观看此处引用的两个视频:
https://msdn.microsoft.com/en-us/library/dn481501(v=vs.113).aspx

解决方案 :我们需要做的是欺骗 EF 认为当前数据库是最新的,而不应用这些 CreateTable 命令。同时,我们仍然希望这些命令存在,以便我们可以创建新的本地数据库。

第 1 步:生产数据库清理
首先,备份您的生产数据库。在 SSMS 中,右键单击数据库,选择“任务 > 导出数据层应用程序...”并按照提示操作。
打开您的生产数据库并删除/删除 dbo.__MigrationHistory 表。

第二步:本地环境清理
打开您的迁移文件夹并将其删除。我假设您可以在必要时从 git 中取回这一切。

第 3 步:重新创建初始
在包管理器中,运行“Enable-Migrations”(如果您有多个上下文,EF 将提示您使用 -ContextTypeName)。
运行“Add-Migration Initial -verbose”。这将创建初始脚本以根据当前代码从头开始创建数据库。
如果您在之前的 Configuration.cs 中有任何种子操作,请将其复制过来。

第 4 步:欺骗 EF
此时,如果我们运行 更新-数据库 ,我们会得到原始错误。因此,我们需要让 EF 认为它是最新的,而无需运行这些命令。因此,进入您刚刚创建的初始迁移中的 Up 方法并将其全部注释掉。

第 5 步:更新数据库
由于没有要在 Up 进程上执行的代码,EF 将使用正确的条目创建 dbo.__MigrationHistory 表,以说明它正确运行了此脚本。喜欢的话就去看看吧。
现在,取消注释该代码并保存。
您可以运行 更新-数据库如果你想检查 EF 是否认为它是最新的。它不会使用所有 CreateTable 命令运行 Up 步骤,因为它认为它已经完成了。

第 6 步:确认 EF 确实是最新的
如果您有尚未应用迁移的代码,这就是我所做的......

运行“Add-Migration MissingMigrations”
这实际上将创建一个空脚本。因为代码已经存在,所以在初始迁移脚本中实际上有创建这些表的正确命令,所以我只是将 CreateTable 和等效的 drop 命令剪切到 Up 和 Down 方法中。

现在,运行 更新-数据库再次观察它执行您的新迁移脚本,在数据库中创建适当的表。

第七步:再次确认并提交。
构建、测试、运行。确保一切都在运行,然后提交更改。

第 8 步:让团队的其他成员知道如何继续。
当下一个人更新时,EF 将不知道是什么击中了它,因为它之前运行的脚本不存在。但是,假设本地数据库可以被吹走并重新创建,这一切都很好。他们将需要删除他们的本地数据库并再次从 EF 添加创建它。如果他们有本地更改和挂起的迁移,我建议他们在 master 上再次创建他们的数据库,切换到他们的功能分支并从头开始重新创建这些迁移脚本。

关于c# - 在模型更改时更新数据库架构而不会丢失数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9389585/

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