You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core .NET 8中如何通过T4模板使用DbContext生成控制器?

T4在.NET 8+EF Core 8环境下读取跨项目DbContext生成控制器的解决方案

一、T4对ASP.NET Core的支持说明

T4完全支持ASP.NET Core(包括.NET 8版本),你遇到的程序集加载错误,核心原因是T4模板运行时的程序集解析上下文与目标项目不一致,尤其是跨项目引用时的依赖加载逻辑未配置正确。

二、分步解决问题

1. 配置T4模板的基础依赖引用

在T4文件开头添加以下指令,明确引用EF Core组件和DbContext所在项目的编译产物:

<#@ template language="C#" debug="true" hostspecific="true" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="Microsoft.EntityFrameworkCore, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60" #>
<#@ assembly name="Microsoft.EntityFrameworkCore.Design, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60" #>
<!-- 替换为你的DbContext项目编译输出路径 -->
<#@ assembly name="$(SolutionDir)YourDbContextProject\bin\Debug\net8.0\YourDbContextProject.dll" #>
<#@ import namespace="Microsoft.EntityFrameworkCore" #>
<#@ import namespace="Microsoft.EntityFrameworkCore.Metadata" #>
<#@ import namespace="YourDbContextProject.Models" #>
<#@ import namespace="System.Linq" #>

注意:将YourDbContextProject替换为实际项目名称,确保路径指向项目编译后的DLL文件。

2. 修复System.Runtime等共享框架依赖加载问题

T4默认运行时无法自动解析.NET Core共享框架的依赖,需手动添加路径解析逻辑:

<#
// 获取.NET 8共享框架的安装路径
var netCoreRuntimePath = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
AppDomain.CurrentDomain.AppendPrivatePath(netCoreRuntimePath);

// 手动加载缺失的核心依赖
LoadRequiredAssembly("System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
LoadRequiredAssembly("System.ComponentModel.Annotations, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
#>

<#+
private void LoadRequiredAssembly(string assemblyFullName)
{
    try
    {
        System.Reflection.Assembly.Load(assemblyFullName);
    }
    catch (System.IO.FileNotFoundException)
    {
        // 从共享框架路径手动加载
        var assemblyFileName = assemblyFullName.Split(',')[0] + ".dll";
        var assemblyPath = System.IO.Path.Combine(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(), assemblyFileName);
        if (System.IO.File.Exists(assemblyPath))
        {
            System.Reflection.Assembly.LoadFrom(assemblyPath);
        }
    }
}
#>

3. 正确读取DbContext模型元数据

无需建立真实数据库连接,只需构造DbContext的空配置即可读取模型结构:

<#
// 构造空的DbContext配置,仅用于读取元数据
var optionsBuilder = new DbContextOptionsBuilder<YourDbContext>();
// 只需传入格式合法的连接字符串,无需真实可用
optionsBuilder.UseSqlServer("Server=.;Database=Dummy;Trusted_Connection=True;");

using (var dbContext = new YourDbContext(optionsBuilder.Options))
{
    foreach (var entityType in dbContext.Model.GetEntityTypes())
    {
        // 跳过Owned实体和系统内置实体
        if (entityType.IsOwned() || entityType.ClrType.Namespace?.StartsWith("Microsoft") == true)
            continue;
        
        // 生成控制器代码的核心逻辑
        WriteLine($"// 生成 {entityType.ClrType.Name} 控制器");
        WriteLine($"public class {entityType.ClrType.Name}Controller : ControllerBase");
        WriteLine("{");
        // 补充控制器的具体代码(如CRUD方法)
        WriteLine("}");
        WriteLine();
    }
}
#>

4. 跨项目引用的额外配置

  • 确保DbContext所在项目已编译成功,生成的DLL文件路径正确。
  • 在Visual Studio中,右键T4文件→属性,将「自定义工具」设为TextTemplatingFileGenerator,并勾选「保存时运行自定义工具」。
  • 若仍有缓存问题,可清理解决方案后重新编译所有项目。

三、常见错误排查

  • 程序集找不到:检查<#@ assembly #>指令中的路径是否正确,确认目标项目已完成编译。
  • 版本冲突:确保T4中引用的EF Core版本与DbContext项目的版本完全一致(均为8.0.0.0)。
  • 权限报错:确认T4模板有读取目标项目输出目录的权限。

内容的提问来源于stack exchange,提问作者Olivertech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 19:12:43