zoukankan      html  css  js  c++  java
  • CodeFirst时使用T4模板

    我们都知道T4模板用于生成相似代码。

    在DBFirst和ModelFirst条件下我们很容易从.edmx下获取所有实体类和其名称,并且通过我们定义的模板和某些遍历工作为我们生成所需要的相似代码。

    但是CodeFirst模式下,我们没有edmx,从哪获取所有类名呢?难道要我们一个个把Entity实体层类名写进数组里吗,十个百个千个?

    解决过程:

    1.使用反射获取所有类名,并将此段代码写到T4模板中。

                    foreach (Type t in Assembly.Load("Entity").GetTypes())
                    {
                        //你对这些类信息的操作
                        //e.g:
                        if (t.FullName == "Entity.baseEntity")
                        {
    
                        }
                        else
                        {
                            string fullName = t.FullName;
                            int length = fullName.Length;
                            int index = fullName.LastIndexOf('.');
                            string classname = fullName.Substring(index + 1, length - index - 1);
                            nameStr += (classname) + ",";
                            
                        }
    
    
                    }
    

    2.结果如上代码可以加载程序集并且获取所有类名,可以自行断点查看。当我们把这段代码放到T4模板中,报错信息却是不能加载程序集。(看见了运行时文本模板,还没尝试那个模板是否有效)

    3.最后实在没办法了,我在应用中创建了一个名为HelpTool的控制台程序。讲上段代码在Main中改写如下:

          static void Main(string[] args)
            {
                using (StreamWriter writer = new StreamWriter("D:\EntitiesNames.txt"))
                {
                    string classNameStr = "";
                    foreach (Type t in Assembly.Load("Entity").GetTypes())
                    {
                        if (t.FullName == "Entity.BaseEntity" || t.FullName == "Entity.DbContextFactory" || t.FullName == "Entity.WeDbContext")
                        {
    
                        }
                        else
                        {
                            string fullName = t.FullName;
                            int length = fullName.Length;
                            int index = fullName.LastIndexOf('.');
                            string classname = fullName.Substring(index + 1, length - index - 1);
                            classNameStr += (classname) + ",";
                        }
                    }
                    writer.Write("");
                    writer.Write(classNameStr);
                    //Console.WriteLine("WriteClassNameSuccessfully");
                    //Console.ReadKey();
                }
            }
    

    4.很明确,我将它写到文本文件里,每次修改实体类,我都要运行一下我的控制台应用。

    5.在T4模板中读取文本文件。例如:

    得到所有实体类的名,存到数组中,并遍历生成相似代码。

    <#@ template language="C#" debug="false" hostspecific="true"#>
    <#@ include file="EF.Utility.CS.ttinclude"#>
    <#@ output extension=".cs"#> 
    
    
    <#
    string[] className=new string[]{""};
    using (StreamReader reader = new StreamReader("D:\EntitiesNames.txt"))
     {
         string nameStr = reader.ReadToEnd();
    	 int index=nameStr.LastIndexOf(',');
    	 nameStr=nameStr.Substring(0,index);
         className= nameStr.Split(',');
     }
    
    
    #>
    
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using DalFactory;
    using Entity;
    using s2s.IDAL;
    
    namespace s2s.UnitOfWork
    {
            public partial class UnitWork
    	{
    <#
    foreach (var entity in className)
    {	
    #>	
    	
    	        public I<#=entity#>Dal <#=entity#>Dal
                    {
                            get { return AbstractDalFactory.GetInstance("<#=entity#>Dal") as I<#=entity#>Dal; }
                    }
    
    <#}#>
    	}
    }
    

    我知道这个方法很笨,谈不上好方案,在遇到问题,coder们总能提出各种各样的解决方案。

    希望园子里的朋友们推荐好的方案,多多指教。

  • 相关阅读:
    网络分析(二)定向与非定向
    Flex 找不到html文件,不能自动生成html问题解决
    常用的功能点记录
    git常规操作命令整理
    语境驱动测试7原则
    探索式测试的问与答
    测试建模:Google ACC
    探索式测试:基于测程的测试管理(SessionBased Test Management)
    用Excel展示SQL Server中的数据 (III): IronPython与自动化
    在Ajax中使用Flash实现跨域数据读取
  • 原文地址:https://www.cnblogs.com/tdws/p/5269334.html
Copyright © 2011-2022 走看看