在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下改变数据库脚本的生成方式的更多相关文章

  1. Entity Framework 之Database first(数据库优先)&Model First(模型优先)

    一.什么是Entity Framework 1.1 实体框架(EF)是一个对象关系映射器,使.NET开发人员使用特定于域的对象与关系数据.它消除了需要开发人员通常需要编写的大部分数据访问代码.简化了原 ...

  2. C# ORM—Entity Framework 之Database first(数据库优先)&Model First(模型优先)(一)

    一.什么是Entity Framework 1.1 实体框架(EF)是一个对象关系映射器,使.NET开发人员使用特定于域的对象与关系数据.它消除了需要开发人员通常需要编写的大部分数据访问代码.简化了原 ...

  3. [UWP小白日记-11]在UWP中使用Entity Framework Core(Entity Framework 7)操作SQLite数据库(一)

    前言 本文中,您将创建一个通用应用程序(UWP),使用Entity Framework Core(Entity Framework 7)框架在SQLite数据库上执行基本的数据访问. 准备: Enti ...

  4. Entity FrameWork 中使用Lambda访问数据库性能优化

    在使用Entity Framework 访问数据库时,我们经常使用Lambda表达式,但是如果不小心的话,很容易就掉到坑里了.比如下面的例子:用Lambda访问MSSqlServer中的NewsInf ...

  5. 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 ...

  6. Entity Framework 在Vs2012下Update Model From DataBase 失败的问题

    http://stackoverflow.com/questions/13054212/vs-2012-ef-5-0-update-model-from-database-not-picking-up ...

  7. Entity FrameWork Code First 之 MVC4 数据库初始化策略用法

    通过启用迁移和更新数据库可以很容易的生成一张表.但是对数据库修改之后,通过数据迁移就没那么好实现了. 这里用到数据库生成策略,进行对数据库操作: 一.3种主要数据库生成策略 1 CreateDatab ...

  8. Entity FrameWork Code First无法生成数据库 解决办法

    我是控制台应用程序,没有connectionStrings,试了几个方法也都不可以. 这是别人的博客用其他方法. http://www.cnblogs.com/Gyoung/archive/2013/ ...

  9. Entity Framework EF6使用 MySql创建数据库异常解决办法

    EF6使用MySQL数据库时,第一次创建数据库出现“Specified key was too long; max key length is 767 bytes”错误,解决办法请见以下连接. htt ...

随机推荐

  1. Web 入门之 XML

      160916   1. 什么是XML?   XML 是 EXtensible Markup Language 的缩写,称为可扩展标记语言,所谓可扩展指用户可根据XML规则自定义标记.例子1-1 = ...

  2. Android_SQLite数据库增删改查操作

    一:什么是SQLite? 在Android平台上,集成了一个嵌入式关系型轻量级的数据库. 二:什么时候用的数据库? 有大量相似机构的数据需要存储时. 三:如何创建一个数据库? 1.创建一个Sqlite ...

  3. c++用法的学习心得

    关于C++这门课,是我在大一的时候开始学习的,那时候接触的就是单纯的一些C++的基本语法规则,基本的编程规则.但是我们都有这样的困惑:课堂和教材的 内容基本上都能接受和理解,但真要实际动手编写程序又感 ...

  4. RazorEngine 3.3 在Mono 3.2上正常运行

    RazorEngine 是一个简化的模板引擎基于微软新的Razor 解析引擎, Razor是在 ASP.NET MVC3 和 Web Pages中引入的.RazorEngine 提供了一个外包装和额外 ...

  5. ABP理论学习之日志记录

    返回总目录 本篇目录 服务端 获取Logger 基类中的Logger 配置 客户端 服务端 ABP使用的是Castle Windsor的日志记录设备.它可以和不同的日志类库一起工作,比如Log4Net ...

  6. ABP理论学习之Nuget包

    返回总目录 本篇目录 框架 测试基 ABP已经发布在Nuget上,这里是所有包的列表. 框架 Abp Abp系统的核心包.所有其他的包都依赖这个包. Abp.Web 提供了MVC和Web API都使用 ...

  7. 轻量级ORM框架初探-Dapper与PetaPoco的基本使用

    一.EntityFramework EF是传统的ORM框架,也是一个比较重量级的ORM框架.这里仍然使用EF的原因在于为了突出轻量级ORM框架的性能,所谓有对比才有更优的选择. 1.1 准备一张数据库 ...

  8. Mac OS X上IntelliJ IDEA 13与Tomcat 8的Java Web开发环境搭建

    这标题实在有点拗口,不知道怎么写好,但看了标题也就明白文本的内容.最近几天在折腾这些玩意儿,所以写写总结.除了环境搭建,本文还是一篇入门级的上手教程. 去下载一些东西 JDK安装 Tomcat安装 T ...

  9. 常用网络工具 ipconfig arp traceroute

    如今的计算机是离不开网络的计算机了,因而我们对网络要有一基础的认识.连不上网,程序运行不正常之类的,多少都与网络有关.本文将介绍常用的工具. 网络出问题 ipconfig ping 网络连不上,首先要 ...

  10. SQL Server 2012故障转移的looksalive check和is alive check

    什么是looksalive check和is alive check SQL Server故障转移集群是建立在windows集群服务上的一种热备的高可用方案.在集群运行过程中,windows集群服务定 ...