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执行日志的解决方案的需求 ...
随机推荐
- Android Context作用
Context 用于访问全局信息的接口 App的资源: strings, drawable资源等等 工程代码:LearnContext.zip ---------------------------- ...
- Python学习 - 使用BeautifulSoup来解析网页一:基础入门
写技术博客主要就是总结和交流的,如果文章用错,请指正啊! 以前一直在使用SGMLParser,这个太费时间和精力了,现在为了毕业设计,改用BeautifulSoup来实现HTML页面的解析工作的. 一 ...
- python中去掉空行的问题
在python中处理空行时,经常会遇到一些问题.现总结经验如下: 1.遇到的空行如果只有换行符,直接使用=='\n'或者 len(line)==line.count('\n') 2.有多个空格+换行符 ...
- 在 LINQ to Entities 查询中无法构造实体或复杂类型
public List<CustomerType> GetCustomerTypesBySchemaTypeCode(int schemaTypeCode) { var query = ( ...
- SharePoint 2013 如何使用TaxonomyWebTaggingControl 控件
在该文章中,我将介绍如何使用TaxonomyWebTaggingControl控件, 首先我相信您已经在SharePoint Managed Metadata Service里定义Term Sets, ...
- BZOJ 1207 打鼹鼠
Description 鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的.根据这个特点阿Q编写了一个打鼹鼠的游戏:在一个n*n的网格中,在某些时刻鼹鼠会在某一个网格探 ...
- int 和String之间的互转
int -> String int i=12345;String s="";第一种方法:s=i+"";第二种方法:s=String.valueOf(i); ...
- 获取Delphi所有类的类信息
Delphi遍历进程中所有Class的TypeInfo,即便是在implementation中的class或者其他 class的private的子class. 一般普通EXE中的TypeInfo存放在 ...
- 12.HTML编辑器(CKEditor、CKFinder集成)
CKEditor原名为FckEditor,是著名的HTML编辑器,可以在线编辑HTML内容. 配置参考文档:主要将ckeditor中的lang.plugins.skins.ckeditor.js.co ...
- MySQL 没有索引 锁全表
<h3 class="title" style="box-sizing: inherit; margin: 8px 0px 15px; padding: 0px; ...