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

简介:

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

在之前的文本模板(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/archive/2011/07/20/1931107.html,如需转载请自行联系原作者

相关文章
|
2月前
|
数据可视化 网络协议 C#
C#/.NET/.NET Core优秀项目和框架2024年3月简报
公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍、功能特点、使用方式以及部分功能截图等(打不开或者打开GitHub很慢的同学可以优先查看公众号推文,文末一定会附带项目和框架源码地址)。注意:排名不分先后,都是十分优秀的开源项目和框架,每周定期更新分享(欢迎关注公众号:追逐时光者,第一时间获取每周精选分享资讯🔔)。
120 1
|
2月前
|
自然语言处理 C# Windows
C#开源免费的Windows右键菜单管理工具
C#开源免费的Windows右键菜单管理工具
|
2月前
|
C#
C#读取txt文本的行数
C#读取txt文本的行数
101 0
|
2月前
|
IDE C# 开发工具
一个开源轻量级的C#代码格式化工具(支持VS和VS Code)
一个开源轻量级的C#代码格式化工具(支持VS和VS Code)
107 6
|
1月前
|
算法 C#
C#开源实用的工具类库,集成超过1000多种扩展方法
C#开源实用的工具类库,集成超过1000多种扩展方法
|
2月前
|
开发框架 .NET C#
使用C#进行.NET框架开发:深入探索与实战
【5月更文挑战第28天】本文探讨了C#在.NET框架中的应用,展示了其作为强大编程语言的特性,如类型安全、面向对象编程。C#与.NET框架的结合,提供了一站式的开发环境,支持跨平台应用。文中介绍了C#的基础知识,如数据类型、控制结构和面向对象编程,以及.NET的关键技术,包括LINQ、ASP.NET和WPF。通过一个实战案例,展示了如何使用C#和ASP.NET开发Web应用,包括项目创建、数据库设计、模型和控制器编写,以及视图和路由配置。本文旨在揭示C#在.NET开发中的深度和广度,激发开发者探索更多可能性。
|
2月前
|
存储 API C#
C# 实现格式化文本导入到Excel
C# 实现格式化文本导入到Excel
|
2月前
|
存储 SQL 数据库
C# 将 Word 转文本存储到数据库并进行管理
C# 将 Word 转文本存储到数据库并进行管理
108 2
|
2月前
|
存储 SQL 数据库
C# 将 Word 转文本存储到数据库并进行管理
C# 将 Word 转文本存储到数据库并进行管理