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

本文讨论的内容是基于EF4.1版本。文中谈论的现有的数据库不是由EF创建。本文假定你已经对Code First迁移有一定的了解,如果不了解Code First迁移更新数据库可以查看

文章涉及的主题如下:

1、创建模型

2、可迁移性

3、添加一个初始迁移

a、使用现有的schema作为起点

b、以一个空数据库作为起点

4、注意点:

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

b、不是所有的数据库对象都在model中表现出来

一、创建模型

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

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

二、可迁移性

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

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

三、添加一个初始迁移

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

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

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

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

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

四、两种方式的具体操作

方式一:

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

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

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

方式二:

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

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

2、注释掉新创建的迁移中Up方法的所有代码。这样做可以让我们应用产生的迁移到本地数据库并且EF不会去创建已经存在的所有表。

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

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

五、注意事项

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

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

注意以下几点:

a、如果选择方式一

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

b、如果选择方式二

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

如果你想降级你现有的数据库到空的状态,通过手工实现是最简单的方式,你可以手动删除数据库或者所有的数据库表。然后,所有的数据库对象都会被重新创建并被命名为默认的名称,这样这个问题就不会在出现。

(2)如果将来你的model发生了改变就需要改变或者删除其中与其他命名不同的那一个数据库对象,针对你本地数据库的程序将不能正常工作,因为数据库对象名与默认的名称不匹配。然而,针对从头开始创建的数据库的程序是可以工作的,因为数据库对象使用的名称是迁移中默认的名称。

你也可以手动在本地数据库中做这些修改,或者考虑使用迁移从头来创建你的数据库。

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

2、不是所有的数据库对象都在model中变现出来

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

注意以下几点:

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

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

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

时间: 2024-10-08 18:11:10

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

System.InvalidOperationException: 支持“XXX”上下文的模型已在数据库创建后发生更改。请考虑使用 Code First 迁移更新数据库(http://go.microsoft.com/fwlink/?LinkId=238269)。

System.InvalidOperationException: 支持"XXX"上下文的模型已在数据库创建后发生更改.请考虑使用 Code First 迁移更新数据库(http://go.microsoft.com/fwlink/?LinkId=238269). EF发布时遇到的问题(数据库初始化 http://www.cr173.com/html/17941_1.html) public ZujuanWebSiteDataEntities() : base("cloud_

支持“***Context”上下文的模型已在数据库创建后发生更改。请考虑使用 Code First 迁移更新数据库(http://go.microsoft.com/fwlink/?LinkId=238269)。

在用VS进行MVC开发的过程中遇到如下问题: 支持“***Context”上下文的模型已在数据库创建后发生更改.请考虑使用 Code First 迁移更新数据库(http://go.microsoft.com/fwlink/?LinkId=238269). 解决了,把数据库中检测模型变化的表(如上图所示)删除就可以了

"支持“xxx”上下文的模型已在数据库创建后发生更改。请考虑使用 Code First 迁移更新数据库”解决办法

学习Asp.Net MVC4 时,使用EF.本来正常,但是由于修改了一下Model中的一个实体类. 导致这个错误. “支持“xxx”上下文的模型已在数据库创建后发生更改.请考虑使用 Code First 迁移更新数据库”. 为了解决上述错误,在Global.asax文件中在 Application_Start后添加以下语句: Database.SetInitializer(new DropCreateDatabaseIfModelChanges<SalesERPDAL>()); 注意需引入命名

Code First 下自动更新数据库结构(Automatic Migrations)

示例 Web.config <?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramew

3.使用 Code First 迁移更新数据库

提示:基于官方教程 1.更新 SeedData 类,使它提供新列的值. 示例更改如下所示,但可能需要对每个 new Movie 块做出此更改. context.Movie.AddRange( new Movie { Title = "When Harry Met Sally", ReleaseDate = DateTime.Parse("1989-2-12"), Genre = "Romantic Comedy", Price = 7.99M,

C# 使用Code First迁移更新数据库

三步完成迁移: 1. 启用迁移: Enable-Migrations Enable-Migrations -ContextTypeName Mvc4WebSite.Models.MvcGuestbookContext 迁移 Mvc4WebSite项目下的MvcGuestbookContext.迁移成功提示:已为项目 Mvc4WebSite 启用 Code First 迁移. 2. 添加迁移: Add-Migration Add-Migration InitialCreate 3. 将迁移更新到数

Code First 迁移更新数据库

在使用 Code First 方式进行MVC程序设计中,更新数据库操作记录: 1.修改需要更新的Model,如: 在Company中增加一个列名,如下: 修改后将应用程序重新编译,然后选择工具>库程序包管理器>程序包管理控制台,如图:打开控制台,输入enable-migrations -force ,然后回车 运行后在项目项目资源管理器中会出现Migrations文件夹,打开Configuration.cs 文件,将AutomaticMigrationsEnabled 值改为 true.然后在

Entity Framework Code Migration 新建、更新数据库

在Package Manager Console中执行 A:新建数据库: 1.Add-Migration init[名称](为挂起的Model变化添加迁移脚本) 2.Update-Database(将挂起的迁移更新到数据库) ***************************************** B:Model中新增字段 1.Add-Migration init-update[名称-此名称不能与新建数据库时使用的名称相同](为挂起的Model变化添加迁移脚本) 2.Update-Da

SqlServer:此数据库处于单用户模式,导致数据库无法删除的处理

今天在删除一个数据库时,一直报错,大意是:此数据库处理单用户模式,尚在连接当中,无法删除(既使将SQLServer停止后再启动也是如此) 百度之后找到了解决办法,备份于此: USE [master] GO /****** Object: StoredProcedure [dbo].[killspid] Script Date: 03/28/2011 11:01:32 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO --建一个存储过