code first使用t4模板

http://stackoverflow.com/questions/23347093/dbcontext-generator-t4-templates-with-code-first

dbfist使用t4模板edmx文件

codefirst没有edmx文件,只有dbcontext类文件,稍微有点不一样。

第一步、添加EF6.Utility.CS.ttinclude文件

路径为C:Program Files (x86)Microsoft Visual Studio 12.0Common7IDEExtensionsMicrosoftEntity Framework ToolsTemplatesIncludes


第二步、修改此文件

在include文件中有三个方法很重要

public IEnumerable<GlobalItem> CreateEdmItemCollection(string sourcePath)

public XElement LoadRootElement(string sourcePath)

private void ProcessErrors(IEnumerable<EdmSchemaError> errors, string sourceFilePath)

最重要的是LoadRootElement方法,读取xml文件,因为codefirst没有edmx,也没有这样的xml文件,我们就准备一个内存流来存取dbcontext信息。

在里面添加两个方法

public IEnumerable<GlobalItem> CreateEdmItemCollection(DbContext dbContext)
{
    ArgumentNotNull(dbContext, "dbContext");

    var schemaElement = LoadRootElement(dbContext);
    if (schemaElement != null)
    {
        using (var reader = schemaElement.CreateReader())
        {
            IList<EdmSchemaError> errors;
            var itemCollection = EdmItemCollection.Create(new[] { reader }, null, out errors);

            ProcessErrors(errors, dbContext.Database.Connection.ConnectionString);

            return itemCollection ?? new EdmItemCollection();
        }
    }
    return new EdmItemCollection();
}

public XElement LoadRootElement(DbContext dbContext)
{
    ArgumentNotNull(dbContext, "dbContext");

    XElement root;

    using (var stream = new MemoryStream())
    {
        using (var writer = XmlWriter.Create(stream))
        {
            EdmxWriter.WriteEdmx(dbContext, writer);
        }
        stream.Position = 0;

        root = XElement.Load(stream, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);
        root = root.Elements()
            .Where(e => e.Name.LocalName == "Runtime")
            .Elements()
            .Where(e => e.Name.LocalName == "ConceptualModels")
            .Elements()
            .Where(e => e.Name.LocalName == "Schema")
            .FirstOrDefault()
                ?? root;
    }

    return root;
}

然后导入命名空间

<#@ assembly name="System.Data.Entity" #>
<#@ import namespace="System.Data.Entity" #>
<#@ import namespace="System.Data.Entity.Infrastructure" #>

第三步、修改t4文件

生成多个cs文件:

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ assembly name="$(SolutionDir)WebinModel.dll"#>
<#@ include file="EF6.Utility.CS.ttinclude"#><#@ 

 output extension=".txt" encoding="utf-8"#><#
    //模板准备

const string connectionString = @"Server=(LocalDb)v11.0;Database=db;Integrated Security=True;MultipleActiveResultSets=True";
var textTransform = DynamicTextTransformation.Create(this);
var code = new CodeGenerationTools(this);
var ef = new MetadataTools(this);
var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
var    fileManager = EntityFrameworkTemplateFileManager.Create(this);
IEnumerable<GlobalItem> itemCollection;
using (var dbContext = new Model.CodeFirstContext(connectionString))
{
    itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(dbContext);

    if (itemCollection == null)
    {
        return string.Empty;
    }
}
var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);

if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), connectionString))
{
    return string.Empty;
}

//WriteHeader(codeStringGenerator, fileManager);
foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
{
    fileManager.StartNewFile("I"+entity.Name + "BLL.cs");
#>
Model.dll是包含dbcontext文件的类库。
接下来是自己代码
foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
{
    fileManager.StartNewFile("I"+entity.Name + "BLL.cs");
#>


<#
    BeginNamespace(code);
#>
<#=codeStringGenerator.UsingDirectives(inHeader: false)#>

<#="public interface I"+entity.Name+"BLL:IBaseBLL"#>
{

}
<#
    EndNamespace(code);
#>


<# }#>

生成单个cs文件:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IBLL
{

public partial interface IBLLSession
{

<#
   foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
{
#>
    I<#=entity.Name#>BLL I<#= entity.Name #>BLL {get;set;}
<#}#>

}

}

 下面是模板里的一些方法,不要去改动。

 补充:模板里的方法怎么来的。

新建一个ado.net数据文件,连接数据库会得到edmx文件,里面就有,可以copy。

这个是ef6的tt模板,回过头来,我们就是把这个模板头部文件进行修改,读程序集而不是edmx文件。

原文地址:https://www.cnblogs.com/tgdjw/p/4705041.html