实体框架:我应该修改迁移类吗?

fej*_*oco 10 .net c# entity-framework ef-code-first ef-migrations

我希望我理解基本的工作流程.首先我创建一个模型,然后生成初始迁移,然后从中生成一个SQL,好的.我更新了模型,我从中创建了一个新的迁移,并从中创建了一个新的SQL,好的.

假设这是一个单向工作流程,我是否正确?如果我以一种糟糕的方式更改迁移类,它将永远不会反映在我的模型中,如果数据库模式不是它应该是什么,EF将永远不会注意到,我只会得到奇怪的异常,对吧?

如何确保在修改迁移类时,我不会导致不一致?我假设我只能做两件事:第一,添加EF不关心的新数据库对象,第二,以最终使用相同模式的方式更改EF生成的迁移代码(例如,如果EF生成一个drop column和a add column,我可以将其改为a rename column),Down()并且Up()方法必须一致,是这样吗?例如,我可以更改EF关心的架构吗?

Jot*_*aBe 6

注意:我将"添加迁移"称为每次使用Add-Migration自动迁移创建或通过自动迁移自动创建的迁移

注意:当我说"DbContext的状态"时,我指的是首先在代码中完成的模型的定义,即实体,它们的属性,关系和所有其他配置

注意:"DbContext已知"表示DbContext知道的所有类型的数据库对象,例如映射到实体的表或视图.数据库中还有许多其他东西,DbContext不知道,包括未映射到DbContext实体的表和视图

我希望我理解基本的工作流程.首先我创建一个模型,然后生成初始迁移,然后从中生成一个SQL,好的.我更新了模型,我从中创建了一个新的迁移,并从中创建了一个新的SQL,好的.

当然,您可以将数据库架构从一个添加迁移更改为其他添加迁移,无论是升级还是降级,还是之间有多少添加迁移.即,您可以指定源迁移和目标迁移.

假设这是一个单向工作流程,我是否正确?

如果这意味着您只能将代码迁移应用到数据库,那么,它只能从代码到数据库,而不是其他方式.

如果我以一种糟糕的方式更改迁移类,它将永远不会反映在我的模型中,

你为什么这样做?创建迁移只是为了完美地完成它而不会出错.为什么要手工做?添加迁移包括从先前添加的迁移的DbContext状态升级到当前DbContext状态的过程的定义.降级的过程,即返回先前添加的迁移的DbContext状态.如果在修改迁移时不小心,可以将其分解.

如果数据库模式不是它应该是什么,EF将永远不会注意到,我只会得到奇怪的例外,对吧?

不!它与迁移无关.与迁移无关,当实例化DbContext时,模型在内存中创建,并根据数据库模式进行检查.如果不匹配,您将获得例外.但这与迁移无关.

您通常会修改模型,添加迁移并将迁移应用于DB,以便同步DbContext和DB模式.其他选项是修改数据库并使用T4模板对数据库进行反向工程,并从数据库模式中获取DbContext.问题是两者都必须同步,但不管你怎么做都没关系.

如何确保在修改迁移类时,我不会导致不一致?我假设我只能做两件事:第一,添加EF不关心的新数据库对象,第二,以最终使用相同模式的方式更改EF生成的迁移代码(例如,如果EF生成一个drop column和add column,我可以将其更改为重命名列),而Down()和Up()方法必须一致,是这样吗?例如,我可以更改EF关心的架构吗?

不要混淆数据库模式,DbContext和迁移概念.

如上所述,DB和DbContext必须同步.

迁移是实现此同步的简单方法:创建初始模型并添加第一个添加的迁移.然后创建数据库.DbContext和DB模式完美同步.如果您以数据库架构更改且与DbContext不匹配的方式修改迁移会发生什么?您的DbContext和您的数据库架构会有所不同,并且在实例化DbContext时会抛出异常.

但是,为什么DB上有迁移表?

当您将迁移应用于数据库时,将更新数据库的模式,并且会获取当前模式的快照(更确切地说,是由DbContext"已知"而不是整个数据库模式的模式部分) ,并存储在数据库中Model__MigrationHistory表的列中.

迁移知道如何将数据库架构从"源"添加迁移更改为"目标"添加迁移.迁移历史记录表用于验证数据库架构是否与上次应用的迁移一致.即,在应用新迁移之前,迁移通过使用迁移表中存储的快照来验证当前数据库架构在应用上次迁移时是否与架构匹配.如果不匹配,则该过程将失败.如果匹配,则迁移将安全地将"源"添加迁移中的更改应用于"目标"添加迁移,并存储生成的模式的快照.

那么,你怎么能破坏它?

  • 通过修改迁移代码使其与DbContext更改不一致(例如,在迁移中添加新列,而不是在DbContext实体中添加它).
  • 通过修改数据库的方式使数据库模式与应用上次迁移时拍摄的快照不同(因此,当您要应用新迁移时,实际模式和快照将不匹配,并且该过程将失败)

什么可以安全地完成?

任何不会改变DbContext"已知"的DB模式的东西,即:

  • 添加代码中定义的DbContext不"已知"的对象(甚至表)(当然还包括触发器,存储过程,视图......)
  • 添加或删除数据(表中的行),如填充主表
  • 做任何不修改架构的事情(修改安全性,配置等)