基于现有数据库的Code First模式迁移更新数据库

本文讨论的内容是基于EF4.1版本。文中谈论的现有的数据库不是由EF建立。本文假定你已经对Code First迁移有必定的了解,若是不了解Code First迁移更新数据库能够查看sql

文章涉及的主题以下:数据库

一、建立模型测试

二、可迁移性spa

三、添加一个初始迁移对象

       a、使用现有的schema做为起点索引

       b、以一个空数据库做为起点开发

四、注意点:get

      a、默认的/计算的名称可能与现有schema不匹配同步

      b、不是全部的数据库对象都在model中表现出来it

 

1、建立模型

第一步是建立一个以现有数据库为目标的Code First model。

注意:在这个主题中,对模型作任何修改以前按照其他的步骤操做是很重要的,您的模型须要修改数据库模式。下面的步骤须要同步模型与数据库模式。

2、可迁移性

         接下来一步是使数据迁移。你能够在NuGet程序包管理器控制台中运行Enable-Migrations命令来实现。

这个命令将会在你的解决方案中建立名为Migrations的文件夹并在文件夹中建立一个名为Configuration的类。Configuration类是用来为应用程序配置数据迁移的。

3、添加一个初始迁移

        一旦建立了数据库迁移和应用到本地数据库您可能还想将这些更改应用于其余数据库。例如,您的本地数据库多是一个测试数据库,你也可能最终要应用这些更改到生产数据库或其余开发人员测试数据库。这一步有两个选择,你应该选择取决于其余数据库的模式目前是不是空的或与本地数据库的模式是否匹配。

方式一:使用现有的schema做为起点(或做为开始)

        当其余数据库迁移将被应用到有相同的模式的本地数据库时,您应该使用这种方法。例如,若是你目前本地测试数据库匹配v1的生产数据库以后,你将会应用这些迁移来更新生产数据库到v2。

方式二:以一个空数据库做为起点(或者做为开始)

        当数据库迁移应用到空数据库(或者不存在的数据库)时,你应该选择这种方法。例如,若是你使用一个测试数据库来开发你的应用程序,完成以后没有使用数据库迁移而是从头开始建立一个生产数据库。

4、两种方式的具体操做

方式一:

Code First数据库迁移经过模型的快照存储对模型所作的最新变动。由于咱们假设数据库已是当前模型的模式,咱们将生成一个空的(操做)以当前的模型做为一个快照的迁移。

一、在包管理器控制台中运行Add-Migration InitialCreate -IgnoreChanges命令。这条命令会建立一个以当前模型做为快照的空的迁移。

二、在包管理器控制台中运行Update-Database命令。这条命令将会把建立的初始迁移应用到数据库。若是实际的迁移没有包含任何的改变,那么会简单的添加一条记录到__MigrationsHistory 表以代表迁移已经被应用。

方式二:

        在这个方式中,咱们须要使用迁移来从头开始建立整个数据库——包括已经在本地数据库存在的表。咱们将会生成一个包含这种逻辑的初始迁移并以现有的schema来建立。而后,会使迁移应用到咱们现有的数据库中。

一、在包管理器控制台中运行Add-Migration InitialCreate命令。这条命令会在现有的schema中建立迁移。

二、注释掉新建立的迁移中Up方法的全部代码。这样作可让咱们应用产生的迁移到本地数据库而且EF不会去建立已经存在的全部表。

三、在包管理器控制台中运行Update-Database命令。这会在数据库中应用InitialCreate迁移。由于实际上迁移并不包含任何更改,那么会简单的添加一条记录到__MigrationsHistory 表以代表迁移已经被应用。

四、取消Up方法中注释掉的代码。这就意味着当这个迁移被应用到之后的数据库中时在本地数据库中已经存在的schema就会经过迁移被应用。

5、注意事项

一、默认/预测的列或表的名称与现有的数据库的匹配

      迁移为将要迁移建立的表和列都明确地指定了名称。然而,当使用这个迁移的时候会对数据库中其余的对象应用这些指定的默认的名称。迁移中还包括索引和外键约束。当针对现有的schema时,这些默认的名称与实际存在的数据库可能不匹配。

      注意如下几点:

      a、若是选择方式一

            若是未来你的model发生了改变就须要改变或者删除其中与其余命名不一样的那一个数据库对象,同时你须要修改脚手架迁移程序来指定正确的表或列名称。Migrations APIs中有重载的方法,能够经过修改可选的参数来实现修更名称。例如,你的现有的数据库可能有一个Post表,表中包含一个BlogId外键列,列名为IndexFk_BlogId。然而,若是使用迁移中默认的名称会被从新命名为IX_BlogId。若是你修改了model将会致使删除这个索引,你须要修改脚手架DropIndex调用来指定索引名为IndexFk_BlogId。

      b、若是选择方式二

           (1)针对你的本地数据库尝试执行初始迁移中的Down方法可能会失败,由于迁移程序将会尝试删除名字正确的索引和外键。这只会影响你的本地数据库或表而其余的数据库或表将会经过初始迁移中的Up方法来从头建立。

             若是你想降级你现有的数据库到空的状态,经过手工实现是最简单的方式,你能够手动删除数据库或者全部的数据库表。而后,全部的数据库对象都会被从新建立并被命名为默认的名称,这样这个问题就不会在出现。

            (2)若是未来你的model发生了改变就须要改变或者删除其中与其余命名不一样的那一个数据库对象,针对你本地数据库的程序将不能正常工做,由于数据库对象名与默认的名称不匹配。然而,针对从头开始建立的数据库的程序是能够工做的,由于数据库对象使用的名称是迁移中默认的名称。

              你也能够手动在本地数据库中作这些修改,或者考虑使用迁移从头来建立你的数据库。

            (3)使用初始迁移中的Up方法建立的数据库可能与你本地数据库有明显的不一样,由于以索引和外键约束为默认名称的名称会被使用。你也能够获得额外的索引做为迁移将以默认外键列来建立索引——建立出来的数据库可能不是你原来的本地数据库。

二、不是全部的数据库对象都在model中变现出来

      没有在model中表示出来的数据库对象不会被Migrations处理。这些没有在model中表示出来的数据库对象包括视图、存储过程、权限许可、表、索引等等。

      注意如下几点:

      a、无论你选的是方式一仍是方式二,若是之后你修改了model须要修改或删除这些额外的对象,Migrations不会知道发生了什么样的修改。例如,你删除了额外对象中的一列,Migrations将不会知道你删除的是什么。若是想让Migrations知道发生的修改,你须要手动将删除的列添加到脚手架Migration中。

      b、若是你选择方式二,这些额外对象不会被初始的migration的Up方法建立。

     

      若是你但愿Up和Down方法监听这些额外的对象,你能够对Up和Down方法进行修改。对于对象,在Migrations API中不是一开始就被支持的,例如视图,你可使用DbMigration.Sql方法执行SQL来建立或删除这些对象。

相关文章
相关标签/搜索