EF6:编写你自己的code first 数据迁移操作(睡前来一篇,翻译的)
原英文版由EF团队成员 Rowan Miller 在2013年发表,此处只作翻译备忘。
数据迁移提供了一套强类型API,用于执行通用的操作,比如CreateIndex("dbo.Blogs","Url")
。同时,也提供了在一些特殊的情况下用户需要执行特殊SQL的接口,比如Sql("Grant Select On dbo.Blogs to guest);
。当然,这个SQL的接口也有一些缺点——那就是一旦你写了SQL那么就意谓着你的程序不再数据库无关了(比如ORACLE的语法和SQL SERVER有时候并不一样,这造成了不兼容)。
你可以把你需要的强类型API提交给ICECLOW。
创建我们自己的操作
我们打算添加一个允许我们将一张表的权限赋给一个用户的操作。正常情况下,我们希望写一个类似GrantPermission("dbo.Blogs","guest",Permission.Select);
的方法。
首先,我们创建一个MigrationOperation的子类,即一个自定义操作。除了实现IsDestructiveChange这个属性别的不需要任何操作。
using System.Data.Entity.Migrations.Model;
namespace ExtendingMigrations.Migrations
{
public enum Permission
{
Select,
Update,
Delete
}
public class GrantPermissionOperation : MigrationOperation
{
public GrantPermissionOperation(string table, string user, Permission permission)
: base(null)
{
Table = table;
User = user;
Permission = permission;
}
public string Table { get; private set; }
public string User { get; private set; }
public Permission Permission { get; private set; }
//是否为破坏性的修改
public override bool IsDestructiveChange
{
get { return false; }
}
}
}
下面,我们来写一个扩展方法以实现我们想要的功能。我们使用IDbMigration接口,这个接口让我们可以有权限操作DbMigration中不可见的API。(比如下面migration,本身没有AddOperation操作【fuck,这是怎么实现的!】,但是,强制转换为IDbMigration的时候就有了)
using System.Data.Entity.Migrations;
using System.Data.Entity.Migrations.Infrastructure;
namespace ExtendingMigrations.Migrations
{
public static class Extensions
{
public static void GrantPermission(this DbMigration migration, string table, string user, Permission permission)
{
((IDbMigration)migration)
.AddOperation(new GrantPermissionOperation(table, user, permission));
}
}
}
你可以把上面的扩展方法作为普通的方法写在GrantPermissionOperation
类中,但是,假如像我这样使用了扩展方法,那么在类中我们就有更漂亮的写法。如下:
namespace ExtendingMigrations.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class GrantGuestPermissions : DbMigration
{
public override void Up()
{
this.GrantPermission("dbo.Blogs", "guest", Permission.Select);
}
public override void Down()
{
}
}
}
为我们的操作创建SQL
如果我们现在就调试运行我们的新的数据迁移类,那么肯定会出现异常。因为默认的SQL生成器不知道我们的操作流程。不过,我们可以从已经存在的migrator
(迁移器?可以这样叫么?)中继承然后将新的SQL生成逻辑添加到我们的操作中。
using System.Data.Entity.Migrations.Model;
using System.Data.Entity.Migrations.Sql;
namespace ExtendingMigrations.Migrations
{
public class MySqlServerMigrationSqlGenerator : SqlServerMigrationSqlGenerator
{
protected override void Generate(MigrationOperation migrationOperation)
{
var operation = migrationOperation as GrantPermissionOperation;
if (operation != null)
{
using (var writer = Writer())
{
writer.WriteLine(
"GRANT {0} ON {1} TO {2}",
operation.Permission.ToString().ToUpper(),
operation.Table,
operation.User);
Statement(writer);
}
}
}
}
}
注意上面的代码中,Generate
方法被我们重写了,但是,我们却没有执行base.Generate(..);
方法,因为父类的方法不知道如何处理这个逻辑,所以即使调用也会报异常。而且,也只有在我们默认的SQL生成器不知道如何处理我们自定义SQL的时候才会调用我们的Generate(MigrationOperation)
方法。
最后,我们需要在数据迁移配置(migrations configuration)中注册我们新的SQL生成器:
namespace ExtendingMigrations.Migrations
{
using System.Data.Entity.Migrations;
internal sealed class Configuration : DbMigrationsConfiguration<ExtendingMigrations.BloggingContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
// Register our custom generator
SetSqlGenerator("System.Data.SqlClient", new MySqlServerMigrationSqlGenerator());
}
}
}
测试
在我们VS的包管理控制台
中输入Update-Database -Script
,会输出更新数据库(对数据库进行数据迁移)时要执行的SQL脚本,其如下:
GRANT SELECT ON dbo.Blogs TO guest
INSERT [dbo].[__MigrationHistory]([MigrationId], [ContextKey], [Model], [ProductVersion])
VALUES ('201302272012532_GrantGuestPermissions', 'ExtendingMigrations.Migrations.Configuration', 0x1F8B0800000..., '6.0.0-alpha3-20222')
EF6:编写你自己的code first 数据迁移操作(睡前来一篇,翻译的)的更多相关文章
- EF Code First 数据迁移操作
打开执行命令窗体 1.EF Code First创建数据库 PM> Install-Package EntityFramework 2.EF Code First数据库迁移 2.1.生成数据库 ...
- EF Code First 数据迁移配置
这里我想讲清楚code first 数据迁移的两种模式,还有开发环境和生产环境数据迁移的最佳实践. 1.1 数据迁移综述 EF Code first 虽然已经有了几种不同的数据库初始化策略,但是大部分 ...
- 图文详解 解决 MVC4 Code First 数据迁移
在使用Code first生成数据库后 当数据库发生更改时 运行程序就会出现数据已更改的问题 这时可以删除数据库重新生成解决 但是之前的数据就无法保留 为了保留之前的数据库数据 我们需要使用到C ...
- Code First 数据迁移 转
一.为模型更改设置 Code First 数据迁移 1.工具—>库程序包管理器—>程序包管理器控制台—>输入“Enable-Migrations” 或者 Enable-Migrat ...
- 解决 MVC4 Code First 数据迁移 数据库发生更改导致调试失败解决方法(二)
文章转载自:http://www.cnblogs.com/amoniyibeizi/p/4486617.html 前几天学MVC过程中,遇到更改Model类以后,运行程序就会出现数据已更改的问题导致调 ...
- C#+EntityFramework编程方式详细之Code First 数据迁移
在前几篇的C#+EntityFramework编程方式中介绍了C#+EntityFramework编程方式Code First ,Model First以及Dtatabase First 等编程方式, ...
- Code first 数据迁移
前段时间用到了EF,整理一下 EF ,全称Entity FramWork.就是微软以ADO.NET为基础发展的所谓ORM(对象关系映射框架,或者说是数据持久化框架). 简单说就是根据实体对象操作数据库 ...
- EF Core数据迁移操作
摘要 在开发中,使用EF code first方式开发,那么如果涉及到数据表的变更,该如何做呢?当然如果是新项目,删除数据库,然后重新生成就行了,那么如果是线上的项目,数据库中已经有数据了,那么删除数 ...
- redis数据迁移操作
redis客户端连接命令,分别连接旧环境中的主从redis Src目录下./redis-cli -h IP -p PORT 使用info replication 命令找出主redis使用客户端命令连接 ...
随机推荐
- jersey实现跨服务器上传
1.导入跨服务器上传文件jar文件 <dependency> <groupId>commons-io</groupId> <artifactId>com ...
- Hibernate入门1. Hibernate基础知识入门
Hibernate入门1. Hibernate基础知识入门 20131127 前言: 之前学习过Spring框架的知识,但是不要以为自己就可以说掌握了Spring框架了.这样一个庞大的Spring架构 ...
- python虚拟环境的搭建命令mkvirtualenv
windows环境如果同时安装了python3和python2,那么无论在哪个版本安装了virtualenv和virtualenvwrapper-win 通过以下命令设置ptyhon版本路径,即可建立 ...
- iOS如何直接跳转到App Store
在iOS应用中如何直接跳转到AppStore里面?其实这个问题很简单,首先拿到你要跳转到的AppStore地址(URL) 例如:https://itunes.apple.com/us/app/中久便利 ...
- 记一次GreenPlum性能调优
在部署了的GreenPlum集群中进行数据查询时,发现数据量一旦大了,查询一跑就中断,提示某个segment中断了连接. ERROR 58M01 "Error on receive from ...
- 【PL/SQL编程】数据类型说明
1. 数值类型 数值类型主要包括NUMBER.PLS_INTEGER.和BINARY_INTEGER 3种基本类型.NUMBER可以用来存储整数或浮点数,PLS_INTEGER和BINARY_INTE ...
- 访问IO设备
http://blog.csdn.net/goodluckwhh/article/details/16986871 内存屏障主要解决的问题是编译器的优化和CPU的乱序执行.编译器在优化的时候,生成的汇 ...
- Buildroot构建指南--快速上手与实用技巧
Buildroot官方全英文使用手册的链接是https://buildroot.org/downloads/manual/manual.html,需要知道每一个细节的朋友,可以仔细查阅,这篇文章只是我 ...
- React-Native进阶_3.触摸高亮显示TouchableHighlight
在安卓原生ListView 点击 其中一个子视图时,会有高亮效果,这个效果在ReactNative 中通过TouchableHighlight 实现,具体使用如下 4.触摸高亮显示 Touchabl ...
- 每周荐书:机器学习、Java虚拟机、微信开发(评论送书)
每周荐书:机器学习.Java虚拟机.微信开发(评论送书) 感谢大家对每周荐书栏目的支持,先公布下上周中奖名单 年精心雕琢,难得的"理论 + 实战案例 + 趟坑经验"总结 从需求分析 ...