zoukankan      html  css  js  c++  java
  • MVC 之 T4模板简介

    个人网站地址:nee32.com

    一、T4模板内容简介

    为了更好地学习T4模板,我们安装一个插件tangible T4 Editor 在使用了EF生成实体类后,我们会发现一个.tt后缀的文件,它就是T4模板,直接打开 它的内容如下图:

    就是这一个模板,生成了我们需要的类,省去了我们手写的麻烦,提高了工作效率,生成的实体类如下图:

    那么,这些类是如何用T4模板生成出来的?要自定义模板又该如何操作?

    下面来简单介绍下T4模板中的核心代码

    1、全局变量申明

    <#@ template language="C#" debug="false" hostspecific="true"#> //模板指令集 告诉编辑器这是一个模板 用C#语言,
    <#@ include file="EF.Utility.CS.ttinclude"#>  //导入外部的模板
    <#@ output extension=".cs"#>  //输出扩展名为.cs的文件

    上面段代码就是定义要用到的全局变量(如 要映射类的EDMX文件、引用名称空间、实体类集合等...)

    2、生成类顶部注释、实体类名称空间 及 实体类名称和后缀名

    WriteHeader(codeStringGenerator, fileManager);//生成类中的最顶部注释
    foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
    {
        fileManager.StartNewFile(entity.Name + ".cs");//生成类名称以及加.cs后缀名称
        BeginNamespace(code);//生成类名称空间
        ...
    }
    

    这句代码生成的相应类文件如下图

    3、引用空间名称 UsingDirectives 方法

    public string UsingDirectives(bool inHeader, bool includeCollections = true)
        {
            return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
                ? string.Format(
                    CultureInfo.InvariantCulture,
                    "{0}using System;{1}" +
                    "{2}",
                    inHeader ? Environment.NewLine : "",
                    includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
                    inHeader ? "" : Environment.NewLine)
                : "";
        }

    默认引用了System和System.Collections.Generic,如下图:

    4、定义类名 EntityClassOpening方法

    public string EntityClassOpening(EntityType entity)
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} {1}partial class {2}{3}",
                Accessibility.ForType(entity),
                _code.SpaceAfter(_code.AbstractOption(entity)),
                _code.Escape(entity),
                _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
        }

    Accessibility.ForType(entity) 访问修饰符,_code.Escape(entity) 类名称 ,如下图:

    5、生成字段属性 Property方法

    public string Property(EdmProperty edmProperty)
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} {1} {2} {{ {3}get; {4}set; }}",
                Accessibility.ForProperty(edmProperty),
                _typeMapper.GetTypeName(edmProperty.TypeUsage),
                _code.Escape(edmProperty),
                _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
                _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
        }

    Accessibility.ForProperty(edmProperty) 访问修饰符, _typeMapper.GetTypeName(edmProperty.TypeUsage) 字段数据类型,如下图:

    二、T4模板拓展 继承基类、接口

    一般我们在基类中定义一些通用的方法,让子类直接继承使用,先定义如下基类:

    public class IEntity<T> where T : class , new()
        {
            private DbContext db
            {
                get
                {
                    return EFDbContextFactory.GetCurrentDbContext();
                }
            }
    
            /// <summary>
            /// 根据条件查找
            /// </summary>
            /// <param name="where"></param>
            /// <returns></returns>
            public T Find(Expression<Func<T, bool>> where = null)
            {
                if (where == null)
                    return db.Set<T>().FirstOrDefault();
                else
                    return db.Set<T>().Where(where).FirstOrDefault();
            }
        }

    直接修改T4模板中的 定义类名 EntityClassOpening 方法,继承基类的Find方法,修改后的代码如下:

    public string EntityClassOpening(EntityType entity)
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} {1}partial class {2}{3} : IEntity<{2}>",
                Accessibility.ForType(entity),
                _code.SpaceAfter(_code.AbstractOption(entity)),
                _code.Escape(entity),
                _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
        }

    然后直接保存一下,再查看T4模板生成的类,发现它们都自动继承了IEntity类,如下图

    调用 ,直接B_Article model = new B_Article().Find(c => c.UserName == "tess");

  • 相关阅读:
    pycharm鼠标光标变成黑色方块
    华章8月书讯,夏日静心好读书
    测试既是一门科学,也是一门艺术
    计算机科学与技术专业教指委将成立“物联网工程专业教学研究专家组”
    【七夕送好书】转微博获赠书!
    孟岩谈《C++程序设计原理与实践》
    【有奖活动】华章IT15周年,评选您心中最有影响力的10种图书
    《测试之美》连载:创建开源的QA社区
    Web前端开发之“常见模块你真的很了解吗?”
    测试驱动开发简介
  • 原文地址:https://www.cnblogs.com/notevar/p/5672589.html
Copyright © 2011-2022 走看看