转自:http://www.cnblogs.com/huangcong/archive/2011/07/20/1931107.html

在之前的文本模板(T4)初体验中我们已经知道了T4的用处,下面就看看如何用它来实现批量修改实体框架(Entity Framework)中的类名.我们都知道ADO.NET 实体数据模型中有一种方式是以数据库模型来生成数据模型的,这是个很简便的实体数据模型生成的方式,但是因为微软提供的自定义接口不足,我们无法实现对生成的数据模型实体类批量进行修改(至少我上网找了很久没找到方法,哪位大侠知道的请赐教,这困扰我很久了,或者哪个好人做有批量修改软件的,麻烦共享一下哈),当然你可以在edmx文件的视图环境下对表进行一个个的修改,但是这个步骤不仅繁琐,而且当你修改数据库架构,重新生成实体数据框架的时候,之前的手工修改将全部被覆盖,因此一旦有数据库的修改,就是噩梦的开始了.因此,必须找到一个灵活的方法来解决这个办法,而我想到的是用基于T4的ADO.NET 自跟踪实体生成器来解决问题.下面就来看如何实现吧.

需求分析:

最近的一个系统中数据库架构的表结构比较复杂,有几十个表,而一些基础表的名字是以 Base_XXX(XXX为表名) 来命名的,这导致我在用实体数据模型中不得不以如下的方式进行数据操作:

UserCenterEntities dataBase = new UserCenterEntities();
//获取所有用户
dataBase.Base_User.Select(u => u).ToList();

从上面可以看出,数据库中的Base_User表映射的是Base_User类. 但是我希望Base_User表映射的类名为UserEntity.即代码风格希望如下所示:

UserCenterEntities dataBase = new UserCenterEntities();
//获取所有用户
dataBase.UserEntity.Select(u => u).ToList();

当然,大家要说了,这有什么难,最简单的方法就是直接在实体数据模型视图编辑器中修改表映射名称就可以啦:

这个方法固然可行,但是如果要我这样修改几十个表,并且一旦数据库有所修改又得重新全部命名一次,我想我会崩溃的,因此,必须寻求一个合适的方法,那就是使用基于T4的ADO.NET自跟踪实体生成器.下面就看看如何实现的吧.

1) 数据库准备

为了简单演示,我就只创建一个2个表的演示数据库吧,大家请用自己的数据库运行一下SQL语句,生成一个新的数据库.

代码

2) 创建数据实体框架

打开VS2010,创建一个新的控制台工程,在工程上右键--新建项--ADO.NET 实体数据模型:

选择"从数据库生成"--下一步--新建连接--添加我们刚才创建好的TestDB数据库--下一步:

选择所有的数据库对象--完成,这样我们就得到最初的实体数据模型了:

打开Model1.Designer.cs,可以看到2个实体类名都不是我想要的.

好了,下面就看看怎么批量修改实体类名吧,ADO.NET自跟踪实体生成器终于可以粉墨登场啦~

3) 创建ADO.NET自跟踪实体生成器.

在实体数据模型试图编辑器中右键--添加代码生成器--选择ADO.NET 自跟踪实体生成器.

添加之后,我们可以在工程中发现多了2个模板以及同步生成的类文件:

4) 修改Model1.tt模板

打开Model1.tt文件,并且在文件的最后添加如下代码:

接着找到下面这段代码:


// 发出实体类型
foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{
fileManager.StartNewFile(entity.Name + ".cs");
BeginNamespace(namespaceName, code);
WriteEntityTypeSerializationInfo(entity, ItemCollection, code, ef);
#>
<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#><#=entity.BaseType == null ? ": " : ","#>IObjectWithChangeTracker, INotifyPropertyChanged
{
<#

更换为如下代码,并且保存:


// 发出实体类型
foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{
fileManager.StartNewFile(GetClassName(entity.Name,"Entity") + ".cs");
BeginNamespace(namespaceName, code);
WriteEntityTypeSerializationInfo(entity, ItemCollection, code, ef);
#>
<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=GetClassName(code.Escape(entity),"Entity")#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#><#=entity.BaseType == null ?": " : ", "#>IObjectWithChangeTracker, INotifyPropertyChanged
{
<#

之后我们可以看到工程文件的文件名和类名都批量修改为我们想要的名称了:

   

5) 修改Model1.Context.tt模板

打开Model1.Context.tt文件,并且在文件的最后添加如下代码:

接着找到如下代码:


<#
region.Begin("ObjectSet 属性", 2); foreach (EntitySet entitySet in container.BaseEntitySets.OfType<EntitySet>())
{
#> <#=Accessibility.ForReadOnlyProperty(entitySet)#> ObjectSet<<#=code.Escape(entitySet.ElementType)#>> <#=code.Escape(entitySet)#>
{
get { return <#=code.FieldName(entitySet) #> ?? (<#=code.FieldName(entitySet)#> = CreateObjectSet<<#=code.Escape(entitySet.ElementType)#>>("<#=entitySet.Name#>")); }
}
private ObjectSet<<#=code.Escape(entitySet.ElementType)#>> <#=code.FieldName(entitySet)#>;
<#

改为如下代码,并且保存:


<#
region.Begin("ObjectSet 属性", 2); foreach (EntitySet entitySet in container.BaseEntitySets.OfType<EntitySet>())
{
string className = GetClassName(code.Escape(entitySet.ElementType),"Entity");
string entitySetElementType = GetClassName(code.Escape(entitySet.ElementType),"Entity");
#> <#=Accessibility.ForReadOnlyProperty(entitySet)#> ObjectSet<<#=className#>> <#=GetClassName(code.Escape(entitySet),"Entity")#>
{
get { return <#=code.FieldName(entitySet) #> ?? (<#=code.FieldName(entitySet)#> = CreateObjectSet<<#=className#>>("<#=entitySet.Name#>")); }
}
private ObjectSet<<#=entitySetElementType#>> <#=code.FieldName(entitySet)#>;
<#

打开Model1.Context.cs文件,可以看到里面的类名也批量修改为我们想要的了:

6) 测试

作者:黄聪
出处:http://www.cnblogs.com/huangcong/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

C#代码生成工具:文本模板初体验 使用T4批量修改实体框架(Entity Framework)的类名的更多相关文章

  1. ASP.NET Core 3.0 上的gRPC服务模板初体验(多图)

    早就听说ASP.NET Core 3.0中引入了gRPC的服务模板,正好趁着家里电脑刚做了新系统,然后装了VS2019的功夫来体验一把.同时记录体验的过程.如果你也想按照本文的步骤体验的话,那你得先安 ...

  2. 自定义tt文本模板实现MySql指数据库中生成实体类

    自定义tt文本模板实现MySql指数据库中生成实体类 1.在项目中依次点击“添加”/“新建项”,选择“文本模板”,输入名称后点击添加. 2.在Base.tt中添加如下代码. <#@ templa ...

  3. grunt 构建工具(build tool)初体验

    操作环境:win8 系统,建议使用 git bash (window下的命令行工具) 1,安装node.js 官网下载:https://nodejs.org/  直接点击install ,会根据你的操 ...

  4. MVC开发T4代码生成之一----文本模板基础

    T4文本模板 T4全写为Text Template Transformation Toolkit,是一种编程辅助工具,用来使程序代码自(懒)动(猿)生(福)成(利)的工具.MVC开发中大量使用了T4模 ...

  5. 编写 T4 文本模板

    文本模板由以下部件组成: 1)指令 - 控制模板处理方式的元素. 2)文本块 - 直接复制到输出的内容. 3)控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码. 指令: 指令是控制模板 ...

  6. 使用代码生成工具快速生成基于ABP框架的Vue+Element的前端界面

    世界上唯一不变的东西就是变化,我们通过总结变化的规律,以规律来应付变化,一切事情处理起来事半功倍.我们在开发后端服务代码,前端界面代码的时候,界面都是依照一定的规律进行变化的,我们通过抽取数据库信息, ...

  7. LLBLGen代码生成工具

    LLBLGen代码生成工具 下载地址:http://www.llblgen.com/ 最新版本4.2 概述 LLBLGen是一个数据访问的解决方案; 你使用LLBLGen创建实体/域模型,定义了映射和 ...

  8. C#.Net实体代码生成工具(EntitysCodeGenerate)的使用及.NET中的ORM实现

    1 引言 目前大多数项目或产品都使用关系型数据库实现业务数据的存储,这样在开发过程中,常常有一些业务逻辑需要直接用写SQL语句实现,但这样开发的结果是:遍地布满SQL语句.这些藕合较高的SQL语句给系 ...

  9. T4模板之初体验(语法)

    一.什么是T4模板 T4是Text Template Transformation Toolkit(文本模板转换工具包)的四个英文首字母的简称.是微软提供的一种代码生成引擎. 在ADO.NET实体数据 ...

随机推荐

  1. 打开一个activity,让edittext不获得焦点

      在实际开发中,有的页面用到Edittext控件,这时候进入该页面可能会自动弹出输入法,这么显示不太友好,所以需要设置一下让Edittext默认不自动获取焦点.在网上查资料解决办法如下: 在Edit ...

  2. nullable,kindof,泛型新特性

    文章来自: http://blog.csdn.net/majiakun1/article/details/46530245 Overview 自 WWDC 2015 推出和开源 Swift 2.0 后 ...

  3. PAT (Advanced Level) 1074. Reversing Linked List (25)

    简单题. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #in ...

  4. USACO刷题之路

    重拾经典 本科生涯结束了,在大学做的ACM竞赛现在基本忘的差不多了.USACO作为一个经典的题库,本来是面向OI选手的,但是由于题目质量很高所以受到大家的好评,所以我这次就从它开始我的刷题之路吧. 由 ...

  5. hibernate--联合主键--XML

    xml:composite-id 要重写equals,hashCode方法, 还要序列化 1. 新建一个主键类: StudentPK.java, 注意需要序列化.还要重写equals和hashCode ...

  6. Openlayers修改矢量要素并且可捕捉

    <!DOCTYPE html><html> <head> <meta http-equiv="Content-Type" content= ...

  7. input有许多,点击按钮使用form传递文本框的值

    input有许多,点击按钮使用form传递文本框的值 <form name="form1" method="post" action="< ...

  8. MyBatis 3 中使用存储过程

    转:http://zachary-guo.iteye.com/blog/1756689 Mybats 是 iBatis 被 Google 收购后重新命名的一个工程,当然也做了大量的升级.iBatis ...

  9. libtask channel机理及调度理解

    学习golang的时候libtask库的代码是一定要看的,需要深入理解chan和携程的运行机制,下面就结合libtask的源码说明下运行原理,如果理解的有偏差欢迎指正 下面是libtask中Chann ...

  10. Zabbix日志错误总结(持续更新)

    no active checks on server [*.*.*.*:10051]: host [*] not found failed to accept an incoming connecti ...