本文讨论的内容是基于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来创建或删除这些对象。

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

  1. 基于EF Core的Code First模式的DotNetCore快速开发框架

    前言 最近接了几个小单子,因为是小单子,项目规模都比较小,业务相对来说,也比较简单.所以在选择架构的时候,考虑到效率方面的因素,就采取了asp.net+entity framework中的code f ...

  2. 支持“xxxContext”上下文的模型已在数据库创建后发生更改。请考虑使用 Code First 迁移更新数据库

    将项目的数据库连接用户及密码修改后(切换用户,用户名与原来不一样,用户下对象结构一致),报以下错误: 支持“XXXDBContext”上下文的模型已在数据库创建后发生更改.请考虑使用 Code Fir ...

  3. 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持

    前言 距离上一篇文章<基于EF Core的Code First模式的DotNetCore快速开发框架>已过去大半个年头,时光荏苒,岁月如梭...比较尴尬的是,在这大半个年头里,除了日常带娃 ...

  4. C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持 基于EF Core的Code First模式的DotNetCore快速开发框架 【懒人有道】在asp.net core中实现程序集注入

    C# 嵌入dll   在很多时候我们在生成C#exe文件时,如果在工程里调用了dll文件时,那么如果不加以处理的话在生成的exe文件运行时需要连同这个dll一起转移,相比于一个单独干净的exe,这种形 ...

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

    在用VS进行MVC开发的过程中遇到如下问题: 支持“***Context”上下文的模型已在数据库创建后发生更改.请考虑使用 Code First 迁移更新数据库(http://go.microsoft ...

  6. "ApplicationDbContext"(泛指之类的数据库上下文模型)上下文的模型已在数据库创建后发生更改。请考虑使用 Code First 迁移更新数据库。

    一,在我使用自动生成数据库的时候,当你改变了数据库就会出现下面问题 "ApplicationDbContext"(泛指之类的数据库上下文模型)上下文的模型已在数据库创建后发生更改. ...

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

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

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

    支持"EFDbContext"上下文的模型已在数据库创建后发生更改.请考虑使用 Code First 迁移更新数据库(http://go.microsoft.com/fwlink/ ...

  9. 支持“EFDBContext”上下文的模型已在数据库创建后发生更改。请考虑使用 Code First 迁移更新数据库

    在修改数据库表后会出现 支持"EFDBContext"上下文的模型已在数据库创建后发生更改.请考虑使用 Code First 迁移更新数据库 这个问题解决方法: 在Global.a ...

随机推荐

  1. information_schema系列五(表,触发器,视图,存储过程和函数)

    这个系列的文章主要是为了能够让自己了解MySQL5.7的一些系统表,统一做一下备注和使用,也希望分享出来让大家能够有一点点的受益. 1:TABLES TABLES这张表毫无疑问了,就是记录的数据库中表 ...

  2. 《深度探索C++对象模型(Inside The C++ Object Model )》学习笔记

    转载:http://dsqiu.iteye.com/blog/1669614 第一章 关于对象 使用class封装之后的布局成本: class并没有增加成本,data members直接内含在每一个c ...

  3. GDT 学习笔记逻辑地址和线性地址计算,因为是自学,所以这只是我的个人理解,不对的请大家指导。

    在 bochs 刚开始的时候 gdt 是未知的,需要通过实模式的16位代码段初始化 gdt 信息, 在 lgdt 指令之后,即可以使用程序自定义的 GDT 表了. 假如:gdt 初始地址为 0x7c7 ...

  4. 在 Windows 環境下利用 VNC 遠端控管 Mac OS X Server

    Mac OS Server 可以使用 VNC 來遠端控管.不過,在 Mac 上打開這個功能很簡單,要讓 Windows 的 VNC Viewer 連上卻很難,原來是有原因的. 首先我們來看怎麼在 Ma ...

  5. Sharepoint 2010 splist url query for date range

    after many attemps,i'v found that Filter feature support the greater than and less than. ie:http://s ...

  6. U盘安装WIN10专业版

    安装环境1个SSD,2个SATA盘. 安装时把2个SATA盘拔掉,并使SSD在BISO中的地位为0区的MASTER,否则安装时会出现,无法创建当前分区,和新建当前分区. 步骤:下载win10正式专业版 ...

  7. linux入门级常用命令

    1) 关闭Linux系统的命令:init 02) Linux终端:Linux终端也称为虚拟控制台.Linux终端采用字符命令行方式工作,用户通过键盘输入命令,通过Linux终端对系统进行控制.3) 切 ...

  8. sql server 查询和Kill死锁进程

    查询死锁进程语句 select        request_session_id spid,       OBJECT_NAME(resource_associated_entity_id) tab ...

  9. Content is not allowed in prolog ---UTF-8 无bom

  10. 简单的html和css

    整体图太大了,看不太清楚,下面是分开的图 第一张: 第二张: