Entity Framework CodeFirst------数据迁移(二)
众所周知当我们的项目涉及到数据库时,随着需求或大或小的 变更后,我们之前设计好的数据模型会发生部分的更改,导致数据表、或者数据字段的增加、修改等,这个时候我们就需要对数据库结构进行修改,如果我们之前采用codefirst方式生成数据模型,我们如何进行数据结构的更改,这里不得不提EF6的数据迁移功能。
“迁移”是一组有序的步骤,描述如何升级(和降级)数据库架构。这些步骤(称为“迁移”)中的每个步骤均包含一些代码,用于描述要应用的更改。
假如我们需要在Stuednt类增加一个新的字段(我们继续接着使用上一节的例子),我们在Student类中增加一个字段PhoneNumber。
public class Student
{
public int ID { get; set; } public string Name { get; set; } public string Class { get; set; } public int Age { get; set; } public string PhoneNumber { get; set; }
}
接着我们启动控制台程序,继续录入我们Student信息。结果我们发现程序报错,在增加学生实体时报错---The model backing the 'EntityClassContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269),提示在数据库创建后实体模型改变了,请考虑使用CodeFirst 迁移更新数据库。
那么我们如何再CodeFirst模式下进行数据迁移呢,首先第一步我们需要为模型启用 Code First 迁移。打开Nuget程序包管理器控制台,输入启用迁移命令---Enable-Migrations。
在工具----Nuget程序包管理器----程序包管理器控制台--输入命令Enable-Migrations。
一个新的 Migrations 文件夹已添加至项目中,它包含两个文件:
Configuration.cs —这个类允许你去配置如何迁移,对于本文将使用默认的配置。
<时间戳>_InitialCreate.cs — 这个迁移之所以存在是因为我们之前用 Code First 创建了数据库, 在启用迁移前,scaffolded migration 里的代码表示在数据库中已经创建的对象,本文中即为表 Student. 文件名包含一个 timestamp 以便排序(如果之前数据库没有被创建,那么 InitialCreate migration 将不会被创建,相反,当我们第一次调用 Add-Migration 的时候所有表都将归集到一个新的 migration 中)
Code First Migrations 有两个你需要熟悉的命令:
Add-Migration 将 创建下一次基于上一次迁移以来的更改的迁移;
Update-Databse 将任何挂起的迁移应用到数据库
以上面的 Student 类为例,我们增加了一个PhoneNumber字段,这样我们需要使用到迁移功能,命令 Add-Migration 允许我们对迁移命名,我们姑且称之为 AddPhoneNumber,即Add-Migration AddPhoneNumber---对迁移命名,我们可以通过命名来了解此次我们对数据模型做了哪些更改。
在Nuget程序包控制台中运行命令 Add-Migration AddPhoneNumber;一个新的迁移(名称包含 timestamp 前缀)在目录 Migrations 中创建成功,该类记录了我们对数据模型做了什么更改。我们可以通过这个文件对数据模型进行还原等其他的操作,这个我们后面再说。
在程序包管理器控制台中运行 Update-Database 命令。此命令将所有挂起的迁移应用于数据库,因此这些迁移将应用新的 AddPhoneNumber迁移。
提示:在调用 Update-Database 命令查看对数据库执行的 SQL 时,可以使用 –Verbose 开关。
然后我们打开数据库查看我们的表结构是否增加了字段PhoneNumber,我们打开SqlService管理器,表Student查看。确实已经增加了字段PhoneNumber。
到目前为止我们总是将数据库模型迁移至最新模式,假如某一次你修改了某张表的数据格式--增加了字段或者删除了字段,并且将他们迁移了,然而随后你又发现你需要将数据模型迁移会之前的某个时间节点,这个时候我们需要用到数据迁移的回迁功能。(所以我们最好在每次的更改数据模型的时候 使用Add-Migration 保存上一次的数据模型配置 )。
刚才我们为student类增加了一个PhoneNumber属性,现在我们需要将其迁回至最初的状态。我们可以使用命令Update-Database –TargetMigration: name
在 Nuget程序包控制台中运行命令 Update-Database –TargetMigration: InitialCreate即可迁回至最初的状态(这个状态是指启用迁移前的状态,如果数据库有数据,数据会保留)。
如果你想回滚一切至空数据库,可以使用命令 Update-Database –TargetMigration: $InitialDatabase。
如果其它开发人员也希望在他们自己的机器上拥有这些更改,他们只需在我们 check in 代码至 source control 的时候做一次同步即可,一旦他们拥有了这些迁移,只需运行命令 Update-Database 就可以把这些更改应用于本地。但是如果我们想把这些更改推送至测试服务器或生产服务器,我们也许需要一份 SQL 脚本提供给 DBA
在运行 Update-Database 的时候指定 -Specify 标记,我们就能够使得这些更改被写入一个脚本中而不是被应用,我们同时也会为此脚本指定源迁移和目标迁移,例如我们希望产生的脚本是从一个空数据库($InitialDatabase)到最新的版本(AddPhoneNumber 迁移);(注意:如果你没有指定目标迁移,那么迁移将始终更新至最新版本;如果你没有指定源迁移,那么迁移将以数据库目前状态为初始)
在 Nuget控制台中运行命令 Update-Database -Script -SourceMigration: $InitialDatabase -TargetMigration: AddPhoneNumber 。运行成功后我们会得到一顿sql脚本。我们将得到的脚本保存在sqlserver中运行。会得到状态为AddPhoneNumber时的数据库状态。
从 EF6 开始,如果你使用 –SourceMigration $InitialDatabase, 产生的脚本将是幂等的,幂等脚本意味着无论数据库当前处于什么版本/状态,都能升级至最新版本或指定版本(指定 –TargetMigration),生成的脚本包括检查表 __MigrationsHistory 的逻辑以及只更新之前从未更新的
当然有时我们不想建立数据库模型的各个状态变化,我们想做的是所做即所得---即我们做了什么更改数据模型就是什么状态。
你可以通过注册 MigrateDatabaseToLatestVersion 数据库初始化器来实现这一点,数据库初始化器只包含一些逻辑检查用于确保数据库被正确设置,这个逻辑检查将会在AppDomain 的 context 第一次被使用的时候执行。
当我们创建一个初始化器的实例时,需要指定 context type('EntityClassContext' )以及 migrations configuration (Configuration)- 这个迁移配置类是在我们启用迁移时生成的 Migrations 目录下增加的
我们在程序开头假如这句代码。
Database.SetInitializer(new MigrateDatabaseToLatestVersion<EntityClassContext, Configuration>());
同时将Configuration类中的自动启用迁移设为true, AutomaticMigrationsEnabled =true。
下节我们将介绍一下 EF CodeFirst 约定、注释及Fluent API。这也是CodeFirst比较重要的部分。
Entity Framework CodeFirst------数据迁移(二)的更多相关文章
- Entity Framework CodeFirst数据迁移
前言 紧接着前面一篇博文Entity Framework CodeFirst尝试. 我们知道无论是“Database First”还是“Model First”当模型发生改变了都可以通过Visual ...
- Entity Framework Migrations 数据迁移
在使用Entity Framework 过程中,经常会遇到需要变更model 的状况,此时可以使用Migrations ,将每次变更记录以便后续更换机器或是运行在生产环境,持久层可保持一致. 在Pac ...
- Entity Framework Code First 迁移
Entity Framework CodeFirst数据迁移 http://www.cnblogs.com/aehyok/p/3325459.html Entity Framework Code Fi ...
- entity framework codefirst 用户代码未处理DataException,InnerException基础提供程序在open上失败,数据库生成失败
警告:这是一个入门级日志,如果你很了解CodeFirst,那请绕道 背景:这篇日志记录我使用Entity FrameWork CodeFirst时出现的错误和解决问题的过程,虽然有点曲折……勿喷 备注 ...
- 第二篇:Entity Framework CodeFirst & Model 映射
前一篇 第一篇:Entity Framework 简介 我有讲到,ORM 最关键的 Mapping,也提到了最早实现Mapping的技术,就是 特性 + 反射,那Entity Framework 实现 ...
- EF Code-First数据迁移
Code-First数据迁移 首先要通过NuGet将EF升级至最新版本. 新建MVC 4项目MvcMigrationDemo 添加数据模型 Person 和 Department,定义如下: usi ...
- 【EF】EF Code-First数据迁移
Code-First数据迁移 首先要通过NuGet将EF升级至最新版本. 新建MVC 4项目MvcMigrationDemo 添加数据模型 Person 和 Department,定义如下: usi ...
- 第三篇:Entity Framework CodeFirst & Model 映射 续篇 EntityFramework Power Tools 工具使用
上一篇 第二篇:Entity Framework CodeFirst & Model 映射 主要介绍以Fluent API来实作EntityFramework CodeFirst,得到了大家一 ...
- Entity Framework Codefirst的配置步骤
Entity Framework Codefirst的配置步骤: (1) 安装命令: install-package entityframework (2) 创建实体类,注意virtual关键字在导航 ...
- ADO.NET Entity Framework CodeFirst 如何输出日志(EF 5.0)
ADO.NET Entity Framework CodeFirst 如何输出日志(EF4.3) 用的EFProviderWrappers ,这个组件好久没有更新了,对于SQL执行日志的解决方案的需求 ...
随机推荐
- html5系列.基础知识
兼容性问题 创建一个html5页面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...
- Android输入法开发
1. 概念 * IMF: 输入法框架(Input Method Framework) * IM: 输入法(Input Method) * IMS: 输入法服务(Input Method Service ...
- TatukGIS - GisDefs - CreateMSJET 函数
函数名称 CreateMSJET 所在单元 GisDefs 函数原型 function CreateMSJET(const _path: String): String; ...
- 快速傅里叶变换(FFT)
一.FFT的意义 DFT虽然实现了FT的计算机计算,但是计算量大,不适合实时的数字信号处理.FFT算法的出现,使DFT的计算效率更高,速度更快. 二.FFT与DFT的关系 从FT到DFT经过了数字角频 ...
- 原 IOS之NSValue整理
原 IOS之NSValue整理 发表于2年前(2013-02-28 23:02) 阅读(1974) | 评论(0) 5人收藏此文章, 我要收藏 赞3 IOS NSValue 值对象(value o ...
- BZOJ 1051 受欢迎的牛
Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认 ...
- [BZOJ 2326] [HNOI2011] 数学作业 【矩阵乘法】
题目链接:BZOJ - 2326 题目分析 数据范围达到了 10^18 ,显然需要矩阵乘法了! 可以发现,向数字尾部添加一个数字 x 的过程就是 Num = Num * 10^k + x .其中 k ...
- Extjs打开window窗口自动加载html网页
Window inherits the autoLoad config option from Panel. Note that I included all config options below ...
- 清除html的标签和行内样式
function shieldStyle(){ this._styleStartArr=["<span","<p","<strong ...
- Ugly Windows
poj3923:http://poj.org/problem?id=3923 题意:给出两个整数n.m表示屏幕的长宽.屏幕上有一些窗口,每个窗口都是矩形的,窗口的边框用同一个大写字母来表示,不同的窗口 ...