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

时间:2014-05-30 14:26:34

标签: c# .net entity-framework ef-code-first ef-migrations

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

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

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

1 个答案:

答案 0 :(得分:5)

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

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

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

  

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

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

  

我认为这是一个单向的工作流程吗?

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

  

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

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

  

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

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

您通常会修改模型,添加迁移并将迁移应用到数据库,以便同步DbContext和数据库架构。其他选项是修改数据库并使用T4模板对数据库进行反向工程,并从数据库模式中获取DbContext。问题是两者都必须同步,但这并不重要。

  

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

不要混淆数据库架构,DbContext和迁移概念。

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

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

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

当您将迁移应用到数据库时,会更新数据库的架构,以及当前架构的快照(更准确地说,是架构的一部分"已知&# 34;由DbContext,而不是整个数据库模式),并存储在数据库中Model表的__MigrationHistory列中。

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

那么,你怎么能破坏它?

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

可以安全地做些什么?

任何不会改变数据库模式的东西#34;已知"通过DbContext,即:

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