【迁移】—Entity Framework实例详解
好久没有在博客园更新博客了,如今都换了新公司。前段时间写了关于EF迁移的文档,今天拿出来作为这个系列的一篇吧。
一、Entity Framework 迁移命令(get-help EntityFramework)
Enable-Migrations 启用迁移
Add-Migration 为挂起的Model变化添加迁移脚本
Update-Database 将挂起的迁移更新到数据库
Get-Migrations 获取已经应用的迁移
二、自定义迁移
现有一个Demo,有如下Product模型:
- 1: public class Product
- 2: {
- 3:
- 4: public int ProductId { get; set; }
- 5:
- 6: public string ProductName { get; set; }
- 7:
- 8: public decimal Price { get; set; }
- 9:
- 10: }
修改Product,添加如下两个属性:
- 1: public DateTime CreateDate { get; set; }
- 2:
- 3: public string Unit { get; set; }
其中,CreateDate和Unit都是必须的。
1. Enable-Migrations
在Package Manager Console中执行Enable-Migrations启动迁移。
执行get-help Enable-Migrations –detailed 查看Enable-Migrations的详细用法。
-ContextTypeName 指定要使用的Context
-EnableAutomaticMigrations 启动自动迁移
-ProjectName 指定搭建的迁移类添加到的项目
-StartUpProjectName 指定使用的配置文件所在的项目
-ConnectionStringName 指定使用配置文件中连接字符串的名称
-ConnectionString 指定使用的连接字符串
-ConnectionProviderName 指定连接字符串的provider名称
-Force 重写迁移配置
本Demo中执行
- Enable-Migrations -ProjectName Demo.Domain -StartUpProjectName MigrationsDemo
执行结果是:检测到数据库是由database initializer创建,为现有的数据库搭建初始化迁移脚本。本Demo中是在Demo.Domain项目中创建了一个Migrations文件夹,以及Migrations中的2个文件:Configuration.cs和201311010641361_InitialCreate.cs
Configuration 类。此类允许您针对上下文配置迁移的行为。
InitialCreate 迁移。此迁移已在启用迁移之前生成,因为我们事先让 Code First 自动创建了一个数据库。此基架迁移中的代码表示数据库中已创建的对象。
如果尚未创建数据库,则不会将此 InitialCreate 迁移添加到项目中。而是,首次调用 Add-Migration 时,用于创建这些表的代码将为新迁移搭建基架。
2. Add-Migration
在Package Manager Console中执行Add-Migration搭建挂起的Model变化迁移脚本。
执行get-help Add-Migration –detailed查看Add-Migration的详细用法。
-Name 指定自定义脚本的名称
-Force
-ProjectName
-StartUpProjectName
-ConfigurationTypeName 指定使用的迁移配置
-IgnoreChanges 忽略检测到挂起的model改变,创建一个空的迁移。这个选项可用来为已有的数据库启用迁移创建一个初始的,空的迁移。
-ConnectionStringName 指定使用配置文件中连接字符串的名称
-ConnectionString 指定使用的连接字符串
-ConnectionProviderName 指定连接字符串的provider名称
本Demo中执行
- Add-Migration Add_Product_CreateDateAndUnit -ProjectName Demo.Domain
生成的Add_Product_CreateDateAndUnit:
2.1 SQL方法
前面提到CreateDate和Unit都是必须的,像Unit是string类型的,更新到数据库默认值为空,CreateDate默认值为1900/1/1 0:00:00,如下图
如果需要更改CreateDate或Unit的值,可以在Up()中使用Sql方法:
注:更新脚本时,将Unit设为中文,记得加’N’,否则在LocalDB中更新的内容会变成’?’,在SQL Server 2008 R2中没有,无论用什么数据库加上都是一个好习惯!
2.2 IgnoreChanges的使用
如果要映射现有的数据库,可以执行Add-Migration Initial,然后执行 Update-Database
这样就创建了一个初始的迁移。在这个基础上再修改Demo,然后迁移。
3. Update-Database
在Package Manager Console中执行Update-Database将挂起的迁移更新到数据库。
执行get-help Update-Database -detailed查看Add-Migration的详细用法。
-SourceMigration 只有-Script打开时才有效。指定迁移的名称用作更新的起点。忽略则使用最后一次应用的迁移。
-TargetMigration 指定将数据库更新到哪个迁移的名称。
-Script 生成SQL脚本
-Force
-ProjectName
-StartProjectName
- ConfigurationTypeName
-ConnectionStringName 指定使用配置文件中连接字符串的名称
-ConnectionString 指定使用的连接字符串
-ConnectionProviderName 指定连接字符串的provider名称
本Demo中执行
- Update-Database -ProjectName Demo.Domain
3.1 迁移到特定版本
上面提到可以使用-TargetMigration开关将数据库迁移到特定的状态。比如,撤销数据库新添加的CreateDate和Unit字段。执行
- Update-Database -ProjectName Demo.Domain -TargetMigration:InitialCreate
如果要一直回滚到空数据库,可以使用 Update-Database –TargetMigration:0或-TargetMigration:$InitialDatabase命令。
3.2 生成SQL脚本
生成SQL脚本要使用-Script开关,另外两个比较重要的开关是:-SourceMigration和-TargetMigration。
比如我们要生成InitialCreate到 Add_Product_CreateDateAndUnit的迁移SQL脚本,则执行如下命令:
- Update-Database -ProjectName Demo.Domain -Script -SourceMigration:InitialCreate -TargetMigration:Add_Product_CreateDateAndUnit
生成下面的SQL脚本
如果忽略-SourceMigration开关,则使用最后一次应用的迁移作为起点,忽略-TargetMigration,则使用最新迁移作为终点。
4. 应用程序启动时自动升级
通过注册 MigrateDatabaseToLatestVersion 数据库初始值设定项来实现该功能。数据库初始值设定项只是包含用于确保数据库安装正确的某种逻辑。首次在应用程序进程 (AppDomain) 中使用上下文时,将运行此逻辑。
Demo中执行
- Database.SetInitializer(new MigrateDatabaseToLatestVersion<OrderContext, Configuration>());
其中Configuration生成的是internal sealed class,不在一个程序集中需要修改成public
三、使用Migrate.exe迁移
将命令行工具migrate.exe复制到包含迁移配置的程序集位置,可以在VS外部进行迁移操作。
在使用 NuGet 安装实体框架时,migrate.exe 位于下载包的 tools 文件夹中。在 <项目文件夹>\packages\EntityFramework.<版本>\tools 中
有了 migrate.exe 之后,需要将其复制到包含迁移的程序集位置。
如果应用程序面向 .NET 4 而不是 4.5,则还需要将 Redirect.config 复制到这个位置,并将其重命名为 migrate.exe.config。这样,migrate.exe 会让正确的绑定重定向能够找到实体框架程序集。
注意:migrate.exe 目前不支持 x64 程序集。
Migrate.exe的使用
migrate.exe /? 显示帮助信息
migrate assembly [configurationType] [/targetMigration]
[/startUpDirectory] [/startUpConfigurationFile]
[/startUpDataDirectory] [/connectionStringName]
[/connectionString] [/connectionProviderName] [/force] [/verbose]
[/?]
Assembly 指定包含迁移配置类型的程序集
[configurationType] 指定迁移配置类型的名称
[connectionProviderName] 指定连接字符的provider
[connectionString] 指定使用的连接字符串
[connectionStringName] 指定配置文件中使用的连接字符串名称
[force] 表示允许自动迁移引起数据丢失
[startUpConfigurationFile] 指定程序的Web.config或App.config
[startUpDataDirectory] 指定当解析包含|DataDirectory|的连接字符串时使用的目录
[targetMigration] 指定迁移到的版本
[verbose] 指定输出执行的SQL和其他信息到控制台
本Demo中执行
- migrate Demo.Domain.dll /startUpConfigurationFile="MigrationsDemo.exe.config" /targetMigration=” Add_Product_CreateDateAndUnit” /verbose
四、参考文章
五、Demo
【迁移】—Entity Framework实例详解的更多相关文章
- Entity Framework实例详解
Entity Framework Code First的默认行为是使用一系列约定将POCO类映射到表.然而,有时候,不能也不想遵循这些约定,那就需要重写它们.重写默认约定有两种方式:Data Anno ...
- 转:【工欲善其事必先利其器】—Entity Framework实例详解
开始本篇文章之前,先说一下Entity Framework 6 Alpha1在NuGet中已可用,原文链接http://blogs.msdn.com/b/adonet/archive/2012/10/ ...
- 【迁移】—Entity Framework实例详解 转
一.Entity Framework 迁移命令(get-help EntityFramework) Enable-Migrations 启用迁移 Add-Migration 为挂起的Model变化添加 ...
- 【配置属性】—Entity Framework实例详解
Entity Framework Code First的默认行为是使用一系列约定将POCO类映射到表.然而,有时候,不能也不想遵循这些约定,那就需要重写它们.重写默认约定有两种方式:Data Anno ...
- —Entity Framework实例详解
Entity Framework Code First的默认行为是使用一系列约定将POCO类映射到表.然而,有时候,不能也不想遵循这些约定,那就需要重写它们.重写默认约定有两种方式:Data Anno ...
- 【配置关系】—Entity Framework实例详解
实体间的关系,简单来说无非就是一对一.一对多.多对多,根据方向性来说又分为双向和单向.Code First在实体关系上有以下约定: 1. 两个实体,如果一个实体包含一个引用属性,另一个实体包含一个集合 ...
- [转]C#综合揭秘——Entity Framework 并发处理详解
本文转自:http://www.cnblogs.com/leslies2/archive/2012/07/30/2608784.html 引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的 ...
- Linq实战 之 Linq to Sql及Entity Framework操作详解
Linq实战 之 Linq to Sql及Entity Framework操作详解 一:linq to db的框架 1. linq to sql 2. linq to ado.net entity f ...
- C#综合揭秘——Entity Framework 并发处理详解
引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制.从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NET Entity Framework,.NET 都 ...
随机推荐
- Android(Xamarin)之旅(二)
新的一年,新的开始,2016,我要做什么,大家要做什么,啦啦啦. OK,上篇已经介绍了几个简单的控件,这次,我们继续说说控件.但是可能有人认为这有什么难的,问题不在这里,而在于,如果你注意了每一个空间 ...
- JS学习之DOM节点的关系属性封装、克隆节点、Dom中Style常用的一些属性等小结
JS DOM节点: 在JS DOM中节点的关系被定义为节点的属性: 通常有以下几种节点之间的关系: (这里的关系是所有浏览器都支持的) parentNode 父节点 childNodes ...
- php获得ip地址
方法一: <?phpfunction GetIP(){if(!empty($_SERVER["HTTP_CLIENT_IP"])){ $cip = $_SERVER[&quo ...
- Java文件读取
package a.ab; import java.io.*; public class FileWrite { public static void main(String[] args) { Fi ...
- onSaveInstanceState & onRestoreInstanceState
一.onSaveInstanceState Called to retrieve per-instance state from an activity before being killed so ...
- haskell debug
最近在学习haskell这门神奇的语言,但是由于print不方便,程序出错的时候都不知道是怎么回事.网上搜了一把发现有这么一个好东西 import Debug.Trace funct :: Integ ...
- TSQL的连乘
某个需求需要对某一列的值做乘法,网上搜了把确实还真没有直接的聚合函数用于将某一列的值乘起来. 找到了替代的算法: http://jerryyang-wxy.blogspot.com/2012/04/t ...
- MVC中用Jpaginate分页 So easy!(兼容ie家族)
看过几款分页插件,觉得Jpaginate比较简约,样式也比较容易的定制,而且体验也比较好,支持鼠标滑动效果.先上效果图: 整个过程很简单,只需要3步 一.引入相关样式和脚本: 1.MVC4中,用了Bu ...
- [自制简单操作系统] 7、多任务(二)——任务管理自动化&任务休眠
前言 >_<" 这里仿照窗口管理的方式将任务管理也修改成相应的管理模式,这样可以灵活的添加多个任务,而不必每次都要修改任务切换函数:此外还在任务休眠做了尝试,通过将任务挂起和唤醒 ...
- 通俗易懂的深入理解js闭包
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域 ...