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类型了:
如果在产生数据库脚本的时候提示以下错误,请稍许更改一下模型(比如拖动一下模型中的实体等)保存之后再试。
相关文章
- SQL Server 2008 数据库同步的两种方式 (发布、订阅)
- 数据库根据两列数据得到层级关系SQL Queries to Manage Hierarchical or Parent-child Relational Rows in SQL Server
- C# 动态创建SQL数据库(二) 在.net core web项目中生成二维码 后台Post/Get 请求接口 方式 WebForm 页面ajax 请求后台页面 方法 实现输入框小数多 自动进位展示,编辑时实际值不变 快速掌握Gif动态图实现代码 C#处理和对接HTTP接口请求
- 微服务轮子项目(30) -数据库分库分表、部署上线方式
- oracle数据库审计用什么数据库审计软件好?可以用什么方式部署?
- 深入浅出XTTS:Oracle数据库迁移升级利器(附PPT)
- 【数据库】+visual paradigm+下载
- 数据库连接池优化配置(druid,dbcp,c3p0)
- oracle如何利用hostname方式连接数据库
- Python MySQL 数据库连接不同方式
- Python与数据库 sqlalchemy 建立声明层表对象的两种方式
- pg数据库中时间查询的方式
- 九、.net core用orm继承DbContext(数据库上下文)方式操作数据库
- 数据库的存储过程和出发器
- MySQL数据库优化的八种方式(经典必看)
- 浅析Docker数据管理-数据库容器化并持久化:数据卷概念、创建数据卷的2种方式、docker volume用法
- 数据库优化见效快的方式
- Java连接MySQL8.0以上版本数据库方式(将驱动改成新版本的解决办法)
- 【数据库】数据的添加、删除和修改
- 35数据库的增删改查
- Oracle数据库创建只读用户
- 利用拷贝data目录文件的方式迁移mysql数据库
- C#如何以TEXTBOX控件中输入的内容查找数据库其他内容
- Sqlite轻量级本地数据库使用框架,简单的两行代码实现对数据的增删改查,采用接口设计模式,自定义注解,实现类似OrmLite的功能,给予HashMap采用的缓存优化设计,支持本地高并发
- kettle根据时间戳增量的将数据从MySQL同步SQLServer(linux部署脚本启动作业、config.properties 配置数据库)
- docker容器中安装Maria数据库