zoukankan      html  css  js  c++  java
  • Entity Framework Model First下改变数据库脚本的生成方式

    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的属性,用以保存雇员的生日日期。该模型定义如下:

    SNAGHTML7bcee4

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

    image

    现在,让我们来尝试改变Entity Framework Model First下数据库SQL脚本的生成方式,以使得所产生的DayOfBirth字段为date类型。

    实现

    通过使用Entity Framework的Structural Annotation的特性,我们可以很方便地定制SQL脚本的生成方式。

    首先,在Solution Explorer中,找到模型文件(扩展名为edmx的文件),单击鼠标右键,选择Open With选项。在Open With对话框中,选择Automatic Editor Selector:

    SNAGHTML522dd4

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

    image

    • SSDL content:对存储模型的定义
    • CSDL content:对概念模型的定义 - 也就是保存设计器上所设计的模型
    • C-S mapping content:定义了概念模型与存储模型之间的映射

    一看就知道,Entity Framework就是一个ORM框架(废话)。

    接下来,我们要对edmx的概念模型部分做一些修改。修改的目的就是为了给SQL脚本的自动化生成提供一些客户化的信息,以便自动化生成工具能够根据这些客户化信息产生不同的结果。

    我们需要在ConceptualModels节点下的Schema上定义自己的命名空间。例如:

    image

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

    image

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

    image

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

    SNAGHTML1b224f

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

    image

    仍然打开模型设计器,在属性窗口中,设置“DDL Generation Template”属性为“.SSDLToSQL10.tt”,注意路径符“.”,它表示需要使用Solution Explorer下的SSDLToSQL10.tt文件,而不是标准的那个文件。

    最关键的一步,就是修改SSDLToSQL10.tt文件。打开这个文件,找到“Creating all tables”部分,并用以下粉红色高亮部分替换其中的内容:

    image

    注意:我们还需要在这个tt文件的顶部引入System.XML和System.XML.Linq的命名空间:

    1
    2
    3
    4
    <#@ 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类型了:

    image

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

    image

     
     
    分类: .NET/C#
     
  • 相关阅读:
    剑指Offer-30.连续子数组的最大和(C++/Java)
    剑指Offer-29.最小的K个数(C++/Java)
    UVA 1616 Caravan Robbers 商队抢劫者(二分)
    UVA 10570 Meeting with Aliens 外星人聚会
    UVA 11093 Just Finish it up 环形跑道 (贪心)
    UVA 12673 Erratic Expansion 奇怪的气球膨胀 (递推)
    UVA 10954 Add All 全部相加 (Huffman编码)
    UVA 714 Copying Books 抄书 (二分)
    UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)
    codeforecs Gym 100286B Blind Walk
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3543670.html
Copyright © 2011-2022 走看看