Entity Framework-——数据迁移的过程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wlk1229/article/details/79874134

官方文档:https://docs.microsoft.com/zh-cn/ef/index

数据迁移的过程

文章前半部分使用的都是数据库默认的初始化对象,即没有使用函数Database.SetInitializer()修改过数据库初始化对象。后半部分会有初始化对象的介绍。

 

在使用EF时经常会遇到下图中的异常,出现这个异常的原因是,数据库中的表无法与我们的数据模型(class MyContex:DbContext)匹配的原因。

Unableto update database to match the current model because there are pending changesand automatic migration is disabled.

这篇文章就是讲解的是EF数据迁移的过程,数据模型如何与数据库匹配,通过这篇文章你可以理解为什么EF会抛出以上异常,以及如何解决以上异常。这里并不讲解EF中数据迁移如何使用,如果不了解EF的数据迁移请阅读:https://www.cnblogs.com/farb/p/DBMigration.html

不使用数据迁移

EF在不使用迁移,也就是没有使用Enable-Migration命令添加迁移代码,这种情况下我们第一次运行程序,程序会根据我们的数据模型类(class MyContex:DbContext),创建数据库。

创建完数据库后,如果我们数据模型类有更改,如添加字段、更改字段类型、删除字段等等,然后直接运行程序,会有以下异常:

Themodel backing the 'MyContex' context has changed since the database wascreated. Consider using Code First Migrations to update the database.

这个异常的原因和之前的异常是一样,数据模型与数据库不匹配导致的。这中情况下我们没有办法,只能将之前的数据库删除,然后运行程序,重新创建数据库。重新创建的数据库会与我们修改后的数据模型完全匹配。

使用数据迁移

为什么要使用数据迁移,使用数据迁移后,在开发阶段我们可以不用一修改数据模型类,就重新创建数据库,如果是已发布的程序,使用数据迁移,我们很容易将老的数据库升级为新数据库。

使用数据迁移后,第一次启动程序时,数据库的创建不在使用数据模型类,而是使用数据迁移的代码,也就是使用Add-Migration添加的代码或者开启(AutomaticMigrationsEnabled)后系统自动生成的代码。

关闭AutomaticMigrationsEnabled

在AutomaticMigrationsEnabled=false时,程序中的迁移代码都需要使用Add-Migration来添加,以下都是讨论AutomaticMigrationsEnabled=false的情况

1.     Add-Migration

Add-Migration会将当前的数据模型类与数据库进行比较,比较后生成修改数据库的代码。如果程序是第一次调用Add-Migration如果数据库中没有程序的数据库,则Add-Migration会根据数据模型类生成代码,并不需要与数据库比较。

如果使用Enable-Migration开启了数据迁移,没有使用Add-Migration添加迁移代码,第一次启动程序会出现以下异常。

这是因为没有数据迁移代码用于生成数据库,所以数据库也不会生成。在AutomaticMigrationsEnabled=false时解决以上异常,只需要使用Add-Migration命令添加迁移代码就行。

2.    Update-Database

Update-Database根据字面意识为更新数据库,其作用也就是更新数据库。使用Update-Database命令会比较数据库是否已经是应用了所有迁移代码后最新的数据库,如果不是则会将未应用的迁移代码,应用到数据库修改数据库。

当数据库中没有程序的数据库时,Update-Database命令会执行所有的迁移代码生成一个数据库。Update-Database命令在比较数据库时都会用到数据库中的一个表__MigrationHistory,在EF生成的数据库中都会有这个表。这个表会记录当前数据库已经使用了哪些迁移代码,如下__MigrationHistory表,代表当前数据库使用了“两个”迁移代码。

当我们数据模型类用更改时,首先我们需要使用Add-Migration添加迁移代码,然后调用Update-Database更新数据库,这样我们的数据库就与数据模型类一致了,启动时就不会报异常。

开启AutomaticMigrationsEnabled

在AutomaticMigrationsEnabled=true时,程序中的迁移代码可以由程序自动生成,也可以使用Add-Migration添加,以下都是讨论AutomaticMigrationsEnabled=true的情况

AutomaticMigrationsEnabled=true时,系统启动了自动迁移功能,系统可以自动生成迁移代码,我们可以不必手动使用Add-Migration添加迁移代码。我们也可以使用Add-Migration添加迁移代码,添加的过程和之前是一样的,都是比较当前数据库与数据模型类的不同,生成对应的代码。

 

因为有了自动迁移的功能,所以我们可以可以直接使用Update-Database更新数据库,不需要使用Add-Migration添加迁移代码。Update-Database命令会自动生成迁移代码并修改数据库与数据模型一致。如下是使用Update-Database命令自动生成迁移数据库时__MigrationHistory的记录,自动迁移的记录MigrationId是  时间_AutomaticMigration

当有Add-Migration添加迁移代码时,Update-Database会优先使用Add-Migration添加迁移代码,使用Add-Migration添加迁移代码后,数据库与数据模型类仍然不一致,Update-Database会继续生成迁移代码。

数据库初始化

我们可以通过Database类的静态函数Database.SetInitializer修改程序的数据库。默认的情况下使用的是CreateDatabaseIfNotExists<TContext>对象。

 

CreateDatabaseIfNotExists<TContext>初始化对象

CreateDatabaseIfNotExists<TContext>初始化对象的作用,可以从名字很容易理解,就是当数据库不存在时创建一个数据库。如果没有开启迁移创建数据库是根据数据模型类TContext创建的,如果开启的迁移则会使用数据迁移代码生成。

 

当开启自动迁移的时候,如果没有迁移代码,CreateDatabaseIfNotExists<TContext>初始化对象创建数据库时会根据数据模型生成相应的迁移代码,如果程序中有迁移代码,创建数据时只会执行已有的迁移代码,即使数据库与数据模型类不匹配也不会再自动生成相应的迁移代码。

 

MigrateDatabaseToLatestVersion<TContext, TMigrationsConfiguration>初始化对象

MigrateDatabaseToLatestVersion<TContext,TMigrationsConfiguration>初始化对象的作用,也可以很容易的从名字看出来,就是将数据库迁移到最新的版本。

 

MigrateDatabaseToLatestVersion会自动将未应用的迁移代码,应用到数据库中修改数据库。这样我们可以不用手动调用Update-Database命令更新数据库,初始化对象会自动更新数据库。

 

再没有开启自动迁移时,MigrateDatabaseToLatestVersion只会使用Add-Migration生成的迁移代码更新数据库。

 

开启自动迁移时,MigrateDatabaseToLatestVersion会对比数据库与数据模型类比较自动生成迁移代码,并自动更新数据库。

 

在开启自动迁移时,并使用MigrateDatabaseToLatestVersion对象,似乎很方便,因为数据迁移代码可以自动生成,数据库更新也可以自动进行,当我们修改了数据模型类时,数据库会自动更新,完全可以不用管数据库的更新。但实际开发时这种方法并不好,实际开发中会关闭自动迁移,使用MigrateDatabaseToLatestVersion对象。原因如下:

1.      我们可以修改Add-Migration添加迁移代码完成更多的功能,如默认值,修改迁移过程中的数据库中的数据等等。

2.      Add-Migration添加迁移代码会记录我们数据库的修改过程,不会出现“奇怪的问题”。

3.      当发布程序后,因为有Add-Migration添加的迁移代码,如果后续版本迭代,如果需要修改数据库,我们可以很容易的修改,可以很容易的将低版本数据库更新。

 

使用自动迁移会让我们失去对迁移的控制,应为迁移代码完全由程序自己生成并使用,我们没法修改。不使用自动迁移我们可以修改Add-Migration生成的迁移代码,控制整个迁移过程,所以一般不使用自动迁移。


猜你喜欢

转载自blog.csdn.net/wlk1229/article/details/79874134
今日推荐