Entity Framework Model First下改变数据库脚本的生成方式
在Entity Framework Model First下, 一个非常常见的需求是改变数据库脚本的生成方式。这个应用场景是指,当用户在Designer上单击鼠标右键,然后选择Generate Database from Model选项,此时Entity Framework Model First会根据模型产生数据库SQL脚本,并将SQL脚本文件添加到解决方案资源管理器中。
事实上,这个自动化产生的数据库SQL脚本还是会有一些局限性。比如:Model上支持DateTime这一CLR类型,在自动化SQL生成的过程中,Entity Framework会自动使用SQL中的数据类型datetime来产生相应的字段定义,如果我们希望对于某些DateTime类型的属性产生date类型,而不是datetime类型的字段,那么我们就需要对数据库脚本的生成方式做一些修改。
例子
首先看一个例子,我们建立一个非常简单的模型:Employee,在这个Employee实体中会有一个DayOfBirth的属性,用以保存雇员的生日日期。该模型定义如下:

在模型设计器上单击鼠标右键,选择“Generate Database from Model”菜单后,产生的SQL语句如下,可以看到,对于DayOfBirth属性,产生的字段是datetime类型:

现在,让我们来尝试改变Entity Framework Model First下数据库SQL脚本的生成方式,以使得所产生的DayOfBirth字段为date类型。
实现
通过使用Entity Framework的Structural Annotation的特性,我们可以很方便地定制SQL脚本的生成方式。
首先,在Solution Explorer中,找到模型文件(扩展名为edmx的文件),单击鼠标右键,选择Open With选项。在Open With对话框中,选择Automatic Editor Selector:

此时会关闭模型设计器,并以XML编辑器的方式打开edmx文件。在打开的编辑器中,我们可以看到edmx文件的详细内容。如果模型比较大的话,这个文件的内容也会比较多(有的甚至几千几万行)。总体来看,主要有三个部分:

- SSDL content:对存储模型的定义
- CSDL content:对概念模型的定义 - 也就是保存设计器上所设计的模型
- C-S mapping content:定义了概念模型与存储模型之间的映射
一看就知道,Entity Framework就是一个ORM框架(废话)。
接下来,我们要对edmx的概念模型部分做一些修改。修改的目的就是为了给SQL脚本的自动化生成提供一些客户化的信息,以便自动化生成工具能够根据这些客户化信息产生不同的结果。
我们需要在ConceptualModels节点下的Schema上定义自己的命名空间。例如:

然后,我们自己自定义一个XML标签,并把这个标签应用到概念模型中的DayOfBirth属性上,如下:

注意此处的“edmx:CopyToSSDL”属性,意思是这部分属性需要在产生模型的时候复制到SSDL存储模型中。因为在生成SQL脚本时,转换引擎会读取SSDL中的内容并根据这些内容产生SQL。现在,我们双击edmx文件,并重新在设计器中打开模型。同样在设计器中点击鼠标右键,选择“Generate Database from Model”选项,待SQL脚本重新生成之后,再用XML编辑器打开edmx文件,此时我们会看到,在SSDL部分,先前添加的“custom:SqlType”节点也被复制到了这里,只不过稍许有些变化:

现在,我们需要定制SQL脚本的产生过程。打开模型设计器,在模型设计器的属性编辑窗口中,我们可以看到一个名为“DDL Generation Template”的属性:

它就是主导SQL脚本生成的T4模板文件,现在需要对这个T4文件进行定制。该文件位于%PROGRAMFILES(x86)%\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\DBGen目录下。为了不更改原有的SSDLToSQL10.tt文件,我们将其复制到Solution Explorer中,注意将该文件的BuildAction设置为None,并去掉Custom Tool的设置:

仍然打开模型设计器,在属性窗口中,设置“DDL Generation Template”属性为“.\SSDLToSQL10.tt”,注意路径符“.\”,它表示需要使用Solution Explorer下的SSDLToSQL10.tt文件,而不是标准的那个文件。
最关键的一步,就是修改SSDLToSQL10.tt文件。打开这个文件,找到“Creating all tables”部分,并用以下粉红色高亮部分替换其中的内容:

注意:我们还需要在这个tt文件的顶部引入System.XML和System.XML.Linq的命名空间:
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Xml.Linq" #>
至此,实现部分已经完成。
测试
现在来测试一下效果。双击打开edmx模型,在模型设计器上单击鼠标右键,选择“Generate Database from Model”,然后查看生成的SQL语句。我们发现,DayOfBirth已经变成了date类型了:

如果在产生数据库脚本的时候提示以下错误,请稍许更改一下模型(比如拖动一下模型中的实体等)保存之后再试。

Entity Framework Model First下改变数据库脚本的生成方式的更多相关文章
- Entity Framework 之Database first(数据库优先)&Model First(模型优先)
一.什么是Entity Framework 1.1 实体框架(EF)是一个对象关系映射器,使.NET开发人员使用特定于域的对象与关系数据.它消除了需要开发人员通常需要编写的大部分数据访问代码.简化了原 ...
- C# ORM—Entity Framework 之Database first(数据库优先)&Model First(模型优先)(一)
一.什么是Entity Framework 1.1 实体框架(EF)是一个对象关系映射器,使.NET开发人员使用特定于域的对象与关系数据.它消除了需要开发人员通常需要编写的大部分数据访问代码.简化了原 ...
- [UWP小白日记-11]在UWP中使用Entity Framework Core(Entity Framework 7)操作SQLite数据库(一)
前言 本文中,您将创建一个通用应用程序(UWP),使用Entity Framework Core(Entity Framework 7)框架在SQLite数据库上执行基本的数据访问. 准备: Enti ...
- Entity FrameWork 中使用Lambda访问数据库性能优化
在使用Entity Framework 访问数据库时,我们经常使用Lambda表达式,但是如果不小心的话,很容易就掉到坑里了.比如下面的例子:用Lambda访问MSSqlServer中的NewsInf ...
- How to: Use the Entity Framework Model First in XAF 如何:在 XAF 中使用EF ModelFirst
This topic demonstrates how to use the Model First entity model and a DbContext entity container in ...
- Entity Framework 在Vs2012下Update Model From DataBase 失败的问题
http://stackoverflow.com/questions/13054212/vs-2012-ef-5-0-update-model-from-database-not-picking-up ...
- Entity FrameWork Code First 之 MVC4 数据库初始化策略用法
通过启用迁移和更新数据库可以很容易的生成一张表.但是对数据库修改之后,通过数据迁移就没那么好实现了. 这里用到数据库生成策略,进行对数据库操作: 一.3种主要数据库生成策略 1 CreateDatab ...
- Entity FrameWork Code First无法生成数据库 解决办法
我是控制台应用程序,没有connectionStrings,试了几个方法也都不可以. 这是别人的博客用其他方法. http://www.cnblogs.com/Gyoung/archive/2013/ ...
- Entity Framework EF6使用 MySql创建数据库异常解决办法
EF6使用MySQL数据库时,第一次创建数据库出现“Specified key was too long; max key length is 767 bytes”错误,解决办法请见以下连接. htt ...
随机推荐
- RPC 的概念模型与实现解析
今天分布式应用.云计算.微服务大行其道,作为其技术基石之一的 RPC 你了解多少?一篇 RPC 的技术总结文章,数了下 5k+ 字,略长,可能也不适合休闲的碎片化时间阅读,可以先收藏抽空再细读:) 全 ...
- AngularJS基础入门初探
一.AngularJS简介 1.1 什么是AngularJS (1)一款非常优秀的前端JS框架,可以方便实现MVC/MVVM模式 (2)由Misko Hevery 等人创建,2009年被Google所 ...
- Android动画小记录
今天在做一个头部滑动菜单的时候需要使用TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYD ...
- 深入挖掘.NET序列化机制——实现更易用的序列化方案
.NET框架为程序员提供了“序列化和反序列化”这一有力的工具,使用它,我们能很容易的将内存中的对象图转化为字节流,并在需要的时候再将其恢复.这一技术的典型应用场景包括[1] : 应用程序运行状态的持久 ...
- vmware 安装xp 流水账
1. 分区 PQ分区.1个区,C盘,NTFS. 2. 安装XP 进入ghost,不要选择一键. 然后fromImage, d:\xxx\GHO
- .NET 的 Debug 和 Release build 对执行速度的影响
这篇文章发布于我的 github 博客:原文 在真正开始讨论之前先定义一下 Scope. 本文讨论的范围限于执行速度,内存占用什么的不在评估的范围之内. 本文不讨论算法:编译器带来的优化基本上属于底层 ...
- 移动APP服务端设计开发注意要点
2014年,移动APP的热度丝毫没有减退,怎么为您的移动端app设计良好的服务器端接口(API)呢? 下面谈谈我个人的一些想法. 2014年,移动APP的热度丝毫没有减退,并没有像桌面软件被WEB网站 ...
- java stopwatch 功能
C#中有一个stopwatch的功能,主要是用来监测程序执行时间的.java之前一直都在用如下方式完成: public static void main(String[] args) { long s ...
- 2013 duilib入门简明教程 -- 界面设计器 DuiDesigner (10)
上一个教程讲解了怎么布局最大化.最小化.关闭按钮,但是如果手动去计算这三个按钮的位置和大小的话,非常的不直观,也很不方便. 所以这一章准备介绍duilib的UI设计器,由于这个设计器很 ...
- Sql Server系列:多表连接查询
连接查询是关系数据中最主要的查询,包括内连接.外连接等.通过连接运算符可以实现多个表查询.内连接查询操作列出与连接条件匹配的数据行,它使用比较运算符比较被连接列的列值.SQL Server中的内连接有 ...