ASP.NET MVC+EF框架+EasyUI实现权限管理系列(9)-TT模板的学习
前言:前面我们基本已经完成了一个Demo,我们在后面的权限也就是按照这个Demo的思路来实现的,只需要给底层添加东西,然后实现业务,权限的逻辑业务有点小复杂,所以大家可以先在博客园随便看看权限方面的业务,当然我说到的时候也会在说的,今天我们就来探讨一下TT模板在本项目重的使用,如果你学会了TT模板,可以大大的减少你的代码的书写量,当然对于TT模板我也正在研究中,所以这篇写的都是基础,以后会继续在写的,下面开始今天我们的TT模板的使用学习,谢谢大家的浏览。
1.为什么需要T4模板
(1)当我们项目写到第七篇开始的时候,我们慢慢就会有那种感觉吧,如果我们的数据库实体非常多的话,而且我们的数据库访问接口层(LYZJ.UserLimitMVC.IDAL)的接口也非常多,并且每个实体都对应一个RoleRepository(仓储),UserInfoRepository(仓储),重点是每个实体仓储的内容基本相同,这时候我们就想怎么办呢?如果每个都写的话,工程量大(假如有成千上万个表的话就要写成千上万个实体接口,不敢想象这是什么工程),而且数据库访问层(LYZJ.UserLimitMVC.IDAL)的内容也需要这样写。
(2)上面我们看到的这段文字阐述了一个问题,那么我们有什么办法能够让系统自动的给我们去生成这些东西呢,这时候我们就想到了代码生成器(TT)模板。
(3)既然是代码生成器模板,那就需要我们自己书写模板,只要我们将模板书写好,其他的东西都会帮助我们自动生成。
(4)那么我们介绍的就是微软标准的生成代码的模板,即TT模板。
2.T4模板的创建
(1)首先我们在数据库访问层(LYZJ.UserLimitMVC.DAL)右键添加新建项,然后我们选择常规下面的文本模板选项(在Entity FrameWork5.0中使用的就是TT模板帮助我们生成一些相同的类),起名为MyFirst.TT,也就是我的第一个TT模板的创建,如下图所示:
(2)当我们创建完TT模板之后,首先我们看到的是一段引用代码,代码如下所示:
1 <#@ template debug="false" hostspecific="false" language="C#" #>
2
3 <#@ assembly name="System.Core" #>
4
5 <#@ import namespace="System.Linq" #>
6
7 <#@ import namespace="System.Text" #>
8
9 <#@ import namespace="System.Collections.Generic" #>
10
11 <#@ output extension=".txt" #> 将txt改为cs (3)这时候我们看到第一行里面的language=”C#”,表明我们当前使用的编程语言是C#,最后一行的output表明是一个输出的对象,extension表示输出的后缀是什么,在这里我们要输出类文件,所以将txt改为cs。
3.T4模板的简单小案例
(1)当我们知道TT模板的用处的时候,这时候做为我们初学者的话,我们是不是非常迫切的想知道TT模板是如何编写的呢,下面我就随便写一个循环的模板给大家演示一下神奇之处,代码如下:
1 <#@ template debug="false" hostspecific="false" language="C#" #>
2
3 <#@ assembly name="System.Core" #>
4
5 <#@ import namespace="System.Linq" #>
6
7 <#@ import namespace="System.Text" #>
8
9 <#@ import namespace="System.Collections.Generic" #>
10
11 <#@ output extension=".cs" #>
12
13 using System;
14
15 public class Kencery
16
17 {
18
19 <# for(int i=0;i<10;i++){#>
20
21 public int HYL<#=i#>{get;set;}
22
23 <# }#>
24
25 } (2)在我们WebForm的时候我们是如何来实现C#代码的呢?就是<% %>格式来实现对C#代码的操作,而在TT模板里面我们稍微变化了一下,那就是<# #>。
(3)这段代码很简单,大部分博友应该知道什么意思?如果大家不知道的话可以随时Q我,我们共同探讨,这里就不说了,当我们书写万TT代码的时候,然后我们单击保存的时候就会自动生成一个MyFirst.CS类,对应上面TT模板中代码生成的代码如下:
1 using System;
2
3 public class Kencery
4
5 {
6
7 public int HYL0{get;set;}
8
9 public int HYL1{get;set;}
10
11 public int HYL2{get;set;}
12
13 public int HYL3{get;set;}
14
15 public int HYL4{get;set;}
16
17 public int HYL5{get;set;}
18
19 public int HYL6{get;set;}
20
21 public int HYL7{get;set;}
22
23 public int HYL8{get;set;}
24
25 public int HYL9{get;set;}
26
27 } (4)在TT模板里面有很多的知识点,当然我也没有学到,只是会点简单的东西来使用而已。这篇博客我就将我所会的都写出来了,一般情况下我们很少自己去写TT模板,直接去安装插件或者去网上查找来实现。
4.根据数据库中的表生成所有表对应的仓储
(1)根据上述的介绍我们已经大致的知道了怎么去使用TT模板,下面我们就针对这个项目来实现一个根据数据库中的表生成所有表对应的仓储的TT模板,我们打开数据库访问层(LYZJ.UserLimitMVC.DAL)里面的RoleRepository的代码,复制到我们建立的TT模板中,RoleRepsoitory中的代码如下所示:
1 using System;
2
3 using System.Collections.Generic;
4
5 using System.Linq;
6
7 using System.Text;
8
9 using System.Threading.Tasks;
10
11 using LYZJ.UserLimitMVC.IDAL;
12
13 using LYZJ.UserLimitMVC.Model;
14
15
16 namespace LYZJ.UserLimitMVC.DAL
17
18 {
19
20 public class RoleRepository : BaseRepository<Role>, IRoleRepository
21
22 {
23
26 }
27
28 } (2)然后我们新建一个TT模板IService.TT模板,将上面的代码复制到TT模板中进行修改,首先我们看上面声明的类就是我们读取出数据库中的表名再加上Repository后缀,也就是RoleRepository,然后我们后面的继承的及仓储是固定的,变换一下表名即可。还有后面的接口也是换掉中间的表名,一些细节的东西我在注注释里面都写了,大家可以参考一下,最后就会改成如下的TT模板:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ include file="EF.Utility.CS.ttinclude"#> //引进TT模板的命名空间
<#@ output extension=".cs" #>
<# CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);
string inputFile = @"..\\LYZJ.UserLimitMVC.Model\\DataModel.edmx";
EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();
EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
#>
//使用TT模板生成代码的片段
using System.Data.Objects;
using LYZJ.UserLimitMVC.IDAL;
using LYZJ.UserLimitMVC.Model;
namespace LYZJ.UserLimitMVC.DAL
{
//在这里需要一个for循环来遍历数据库中所有的表放置在下面即可,这样就实现了所有的表对应的仓储显示出来了。
<#
//使用foreach循环遍历ItemCollection.GetItems<EntityType>集合
foreach(EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e=>e.Name))
{ #>
public partial class <#=entity.Name#>Repository : BaseRepository<<#=entity.Name#>>, I<#=entity.Name#>Repository
{
}
<#}#>
} (3)上面的这段TT模板的代码实现了将数据库访问层的实体代码全部转换成cs代码,因为我们现在实体模
补充:Web开发 , ASP.Net ,