之前做项目使用的都是Db First,直接在项目中添加Entity Framework,使用T4模板(T4模板引擎之基础入门)生成DAL BLL层等(T4模板是一个同事给的,也没有仔细研究,代码如下:)

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#>
<#@ 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 = @"..\\TestProject.Model\\EFData.edmx"; EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion(); EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this); #>
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using DianXin.TianYi.Model;
using DianXin.TianYi.IDAL; namespace TestProjectDAL
{
<#
foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{
#>
public partial class <#=entity.Name#>DAL : BaseDAL<<#=entity.Name#>>, I<#=entity.Name#>DAL {}
<#
}
#>
}

现在突然想用一下Code First改变一下(觉得直接在Model上加特性标签,挺爽的,省去再使用“BuddyClass”做验证了),但突然发现上面的代码不能用了,令人感觉有点小郁闷(其实是个人比较懒了),就仔细翻看一下这方面的资料(关于上面代码可以参考:实体框架实用工具.ttinclude文件)。但觉得网上没有介绍在CodeFirst中使用T4生成DAL层的文章或者文章有点太老了,里面方法没有实验成功,也有点让人看不懂。经过七拼八揍终于被我整出来了,其中也遇到了几个小问题,就在这记录一下。

1.关于错误" 正在编译转换: 未能找到类型或命名空间名称“TestProject”(是否缺少 using 指令或程序集引用?) ",是因为直接在T4模板里使用<#@ import namespace="TestProject.Model" #>,才报的这个错,这里要说明一下,如果添加系统引用是没有问题。(eg: <#@ important namespace="System.Data.SqlClient" #>),T4测试代码如下:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="TestProject.Model" #>
<#@ output extension=".cs" #>

解决此问题可以简单分为3步:

第1步,先引入dll文件

代码如下:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ assembly name="$(SolutionDir)\TestProject.Model\bin\Debug\TestProject.Model.dll" #>
<#@ output extension=".cs" #>

其中”$(SolutionDir)“是指解决方案目录,这种称做VS宏的方式。具体有以下几个系统VS宏:

$(SolutionDir) 当前项目所在解决方案目录
$(ProjectDir) 当前项目所在目录
$(TargetPath) 前项目编译输出文件绝对路径
$(TargetDir) 当前项目编译输出目录,即web项目的Bin目录,控制台、类库项目bin目录下的debug或release目录(取决于当前的编译模式)

第2步:在第1步的基础上添加命名空间就可以了,代码如下:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ assembly name="$(SolutionDir)\TestProject.Model\bin\Debug\TestProject.Model.dll" #>
<#@ import namespace="TestProject.Model" #>
<#@ output extension=".cs" #>

第3步:就可以直接写代码了,我的做法是先获得TestContext(这个类继承了DbContext)里的所有属性,判断属性的类型名中包含DbSet的属性,然后再获得属性里的泛型类型数组,就可以获得类。示例代码如下:

TestContext:

public partial class TestContext : DbContext
{
public TestContext() : base("TestDatabase") { } public DbSet<Teacher> Teachers { get; set; } public DbSet<Person> Persons { get; set; } public DbSet<Student> Students { get; set; }
}

EntityClassInfo:(通过该类可以获得TestContext里所有类型为DbSet的类名称)

public class EntityClassInfo
{
public EntityClassInfo()
{
List<string> classNameList = new List<string>();
PropertyInfo[] properties = typeof(TestContext).GetProperties(); // 获得对象所有属性
foreach (var property in properties)
{
string propertyType = property.PropertyType.Name; // 获得属性类型名称
if (propertyType.Contains("DbSet")) // 判断是否为实体集合
{
Type[] genericTypes = property.PropertyType.GenericTypeArguments; // 获得泛型类型数组
foreach (var type in genericTypes)
{
classNameList.Add(type.Name); // 获得泛型类型名称 并添加到集合中
}
}
}
this.EntitiesList = classNameList;
} public List<string> EntitiesList { get; set; }
}

T4代码:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="$(SolutionDir)\TestProject.Model\bin\Debug\TestProject.Model.dll" #>
<#@ import namespace="TestProjectModel" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#
var entity = new EntityClassInfo();
foreach(var item in entity.EntitiesList)
{#>
<#=item#>
<#}#>

参考资料:解决T4模板的程序集引用出错(5种方案)

就这样吧,如有错误之处,请大牛们指出,谢谢

http://www.cnblogs.com/silencealone/p/4534757.html

http://www.cnblogs.com/guomingfeng/p/mvc-ef-t4.html

使用T4模板生成代码的学习的更多相关文章

  1. T4模板生成代码。 数据实体层与数据仓储层。备注

    文件生成模板:TempleteManager.ttinclude <#@ assembly name="System.Core" #><#@ assembly n ...

  2. C# 通过T4自动生成代码

    通过T4模板生成代码,运行时实现 关键代码段:Host using Microsoft.VisualStudio.TextTemplating; using System; using System. ...

  3. MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码

    前言 经过前面EF的<第一篇>与<第二篇>,我们的数据层功能已经较为完善了,但有不少代码相似度较高,比如负责实体映射的 EntityConfiguration,负责仓储操作的I ...

  4. [转]MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码

    本文转自:http://www.cnblogs.com/guomingfeng/p/mvc-ef-t4.html 〇.目录 一.前言 二.工具准备 三.T4代码生成预热 (一) 单文件生成:Hello ...

  5. CSharpGL(12)用T4模板生成CSSL及其renderer代码

    CSharpGL(12)用T4模板生成CSSL及其renderer代码 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立 ...

  6. 【VS外接程序】利用T4模板生成模块代码

    引言 记得第一次做asp.net mvc项目时,可以用model直接生成Html的增删改查页面, 没什么特殊要求都可以不用修改直接用了, 觉得很神奇,效率太高了.后来在做客户端开发时,发现很多模块都是 ...

  7. 使用T4模板生成不同部署环境下的配置文件

    在开发企业级应用的时候,通常会有不同的开发环境,比如有开发环境,测试环境,正式环境,生产环境等.在一份代码部署到不同环境的时候,不同环境的配置文件可能需要根据目标环境不同而不同.比如在开发环境中,数据 ...

  8. 利用T4模板生成ASP.NET Core控制器的构造函数和参数

    前言 在ASP.NET Core中引入了DI,并且通过构造函数注入参数,控制器中会大量使用DI注入各种的配置参数,如果配置注入的参数比较多,而且各个控制器需要的配置参数都基本一样的话,那么不断重复的复 ...

  9. Visual Studio 2013 EF5实体数据模型 EDMX 使用 T4模板生成后使用 ObjectContext对象

    Visual Studio 2013 EF5实体数据模型 EDMX 使用 T4模板生成后的继承对象为DbContext,以前的熟悉的ObjectContext对象不见了,当然使用ObjectConte ...

随机推荐

  1. 主动模式FTP与被动模式FTP该如何选择

    主动模式FTP与被动模式FTP该如何选择  无论是主动模式还是被动模式,其要进行文件传输都必须依次建立两个连接,分别为命令连接与数据连结.而主动模式与被动模式的差异主要体现在数据连结通道上.为了说明两 ...

  2. 给11gR2 Dataguard打psu补丁的步骤及注意事项

    参考文档278641.1 0.备份备主备库的spfile备份主库的数据 1.在主库上暂停向备库传日志alter system set log_archive_dest_state_X=defer sc ...

  3. java基础(二)

    1.equals()方法是可以重写的,因此说equals方法是判断两个对象的值是否相等是不完全正确的,当重写方法时可以定义自己的相等规则. 2.Java中的类可以包含六中元素;属性.方法.代码块.内部 ...

  4. js闭包Demo

    我们先看一个关于Javascript利用循环绑定事件的例子: 例如:一个不确定长度的列表,在鼠标经过某一条的时候改变背景.   ﹤!DOCTYPE html PUBLIC "-//W3C// ...

  5. jquery控制radio选中

    好久没写jquery了,昨天下午写一个效果,结果倒腾了半天还是没有解决,好在今天早上在网上询问到解决方法了,现在果断记录下. 要实现的效果就是交易方式选择时不同的交易方式下默认选中第一个选项. 如下: ...

  6. Linux安装软件总结(二.几种安装命令介绍)

    一.rpm包安装方式步骤: 1.找到相应的软件包,比如soft.version.rpm,下载到本机某个目录: 2.打开一个终端,su -成root用户: 3.cd soft.version.rpm所在 ...

  7. win7下装完ubuntu linux后,开机画面怎直接进入linux了,win7怎么启动

    修复 Windows 7 启动项重新启动ubuntu之后,结果发现选择windows 7的启动项,又进入到Ubuntu的安装界面.下面来说明如何修复,进人Ubuntu系统,打开“应用程序---附件-- ...

  8. css 设置圆角

    CSS3 圆角(border-radius) -moz(例如 -moz-border-radius)用于Firefox -webkit(例如:-webkit-border-radius)用于Safar ...

  9. 百度地图 获取两点坐标之间的驾车距离(非直线距离) c#

    百度接口了解: http://lbsyun.baidu.com/index.php?title=webapi/route-matrix-api-v2 起点与终点为多对多关系,如果你只想取两个坐标,那就 ...

  10. 球谐光照(Spherical Harmonics Lighting)及其应用-实验篇

    简介 之前在一篇实时深度图优化的论文中看到球谐光照(Spherical Harmonics Lighting)的应用,在查阅了许许多多资料之后还是无法完全理解,我个人觉得如果之前对实时渲染技术不是很了 ...