注意:我会将“add-migration”调用到使用Add-Migration 创建的每个迁移,或由自动迁移自动创建的迁移
注意:当我说“DbContext 的状态”时,我指的是首先在代码中完成的模型定义,即实体、它们的属性、关系和所有其他配置
注意:“DbContext 知道”是指 DbContext 知道的所有类型的数据库对象,例如映射到实体的表或视图。 DB 中还有很多其他的东西是 DbContext 不知道的,包括未映射到 DbContext 实体的表和视图
我希望我了解基本的工作流程。首先我创建一个模型,然后我生成一个初始迁移,然后我从中生成一个 SQL,OK。我更新模型,从中创建一个新的迁移,并从中创建一个新的 SQL,好的。
当然,您可以将数据库架构从一个添加迁移更改为另一个添加迁移,无论是升级还是降级,或者两者之间有多少添加迁移。 IE。您可以指定源和目标迁移。
我是否正确地假设这是一个单向工作流程?
如果这意味着您只能将迁移从代码应用到数据库,是的,它只能从代码迁移到数据库,否则不能。
如果我以不好的方式更改迁移类,它将永远不会反映在我的模型中,
你为什么要这样做?创建迁移只是为了完美地做到这一点而不会犯错误。为什么要手动做?添加的迁移包括从先前添加的迁移的 DbContext 状态升级到当前 DbContext 状态的过程的定义。以及降级的过程,即返回到先前添加的迁移的 DbContext 状态。如果你在修改迁移时不小心,你可以打破这个。
如果数据库架构不完全是它应该的样子,EF 永远不会注意到,我只会得到奇怪的异常,对吧?
不!它与迁移无关。独立于迁移,当 DbContext 被实例化时,模型会在内存中创建,并根据 DB 模式进行检查。如果不匹配,您将获得异常。但这与迁移无关。
您通常会修改模型,添加迁移,然后将迁移应用到 DB,以便 DbContext 和 DB 架构同步。其他选项是修改数据库并使用 T4 模板对数据库进行逆向工程并从数据库模式中获取 DbContext。问题是两者都必须同步,但不管你怎么做。
如何确保在修改迁移类时不会导致不一致?我假设我只能做两件事:首先,添加 EF 不关心的新数据库对象,其次,更改 EF 生成的迁移代码,使其最终具有相同的架构(例如,如果 EF 生成一个删除列和添加列,我可以将其更改为重命名列),并且 Down() 和 Up() 方法必须保持一致,仅此而已吗?例如,我可以更改 EF 关心的架构吗?
不要混淆 DB 架构、DbContext 和迁移概念。
如上所述,DB 和 DbContext 必须同步。
迁移是实现这种同步的一种简单方法:您创建初始模型并添加第一个添加迁移。然后创建数据库。 DbContext 和 DB 模式完全同步。如果您以 DB 架构更改且与 DbContext 不匹配的方式修改迁移,会发生什么情况?您的 DbContext 和您的 DB 架构会有所不同,并且在实例化 DbContext 时会引发异常。
但是,为什么数据库上有迁移表?
当您将迁移应用到数据库时,数据库的架构会更新,并且当前架构的快照(更准确地说,是 DbContext “已知”的架构部分,而不是整个 DB Schema) 被取出,并存储在数据库中__MigrationHistory 表的Model 列中。
Migrations 知道如何将数据库架构从“源”添加迁移更改为“目标”添加迁移。迁移历史表用于验证 DB 模式与上次应用的迁移是否一致。 IE。在应用新迁移之前,迁移使用存储在迁移表中的 快照 验证当前数据库架构是否与应用上次迁移时的架构匹配。如果不匹配,则该过程将失败。如果匹配,迁移将安全地将更改从“源”添加迁移应用到“目标”添加迁移,并存储结果架构的快照。
那么,你怎么能破坏东西呢?
- 通过修改迁移代码使其与 DbContext 更改不一致(例如,在迁移中添加新列,而不是在 DbContext 实体中添加)。
- 通过修改数据库,使数据库架构与应用上次迁移时拍摄的快照不同(因此,当您要应用新迁移时,真实架构和快照将不匹配,并且进程会失败)
可以安全地做些什么?
任何不改变 DbContext “已知”的数据库架构的东西,即:
- 添加代码中定义的 DbContext 不“知道”的对象(甚至表)(当然还有触发器、存储过程、视图...)
- 添加或删除数据(表中的行),例如填充主表
- 做任何其他不修改架构的事情(修改安全性、配置等)