Net6 EFCore 基于MSSQL & T4 自动生成字段注释
文件模板代码
T4_GetEntityDic
<#@ template language="C#" #> <#@ output extension=".cs" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.IO" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Text.RegularExpressions" #> <# // 设置生成的文件路径 string dbContextFilePath = @"C:\XXX\Models\Context.cs"; string entityFolderPath = @"C:\XXX\Models";// 实体类文件所在文件夹路径 string dbContextCode = File.ReadAllText(dbContextFilePath); var entityDic = new Dictionary<string, Dictionary<string, string>>(); // 正则匹配:表名,表注释 var entityMatches = Regex.Matches(dbContextCode, @"modelBuilder\.Entity<(.+?)>\(entity =>(.+?)entity\.HasComment\(""(.+?)""\);(.+?)\}", RegexOptions.Singleline); foreach (Match matchEntity in entityMatches) { var entityName = matchEntity.Groups[1].Value; var itemDic = new Dictionary<string, string> { { $"Table - {entityName}", matchEntity.Groups[3].Value} }; entityDic.Add(entityName, itemDic); // 正则匹配:字典名,字典注释 var propertyCode = matchEntity.Groups[4].Value; var propertyMatches = Regex.Matches(propertyCode, @"entity\.Property\(e => e\.(.+?)\)(.+?)HasComment\(""(.+?)""\);", RegexOptions.Singleline); foreach (Match matchProperty in propertyMatches) { itemDic.Add(matchProperty.Groups[1].Value, matchProperty.Groups[3].Value); } } // 只读api的实体名集合:不需要生成增删改接口 var onlyReadApi = new List<string>(); // 不生成控制器 var ignoreBuildApi = new List<string>(); #> //------------------------------------------------------------------------------ // <auto-generated> // 此代码已从模板生成[<#= DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")#>] // // 手动更改此文件可能导致应用程序出现意外的行为 // 如果重新生成代码,将覆盖对此文件的手动更改 // </auto-generated> //------------------------------------------------------------------------------
AddComment
<#@ include file="$(TargetDir)\..\..\..\..\DbModels\T4_GetEntityDic.tt" #> <# // 获取实体类文件夹中的所有文件路径 string[] entityFiles = Directory.GetFiles(entityFolderPath, "*.cs"); // 遍历所有实体类文件,为每个文件添加注释 foreach (var entityFile in entityFiles) { // 排除dbContext文件 if(entityFile == dbContextFilePath) continue; string entityCode = File.ReadAllText(entityFile); // 过滤不存在的字典值 var entityName = Path.GetFileNameWithoutExtension(entityFile); if (!entityDic.ContainsKey(entityName)) continue; var itemDic = entityDic[entityName]; // 拦截重复保存 var isSuccess = Regex.Match(entityCode, @"/summary>(.+?) class", RegexOptions.Singleline).Success; if(isSuccess) continue; // 匹配实体类的注释 var updatedEntityCode = entityCode.Replace(" public partial class ", $@" /// <summary> /// {itemDic[$"Table - {entityName}"]} /// </summary> public partial class "); // 匹配实体类的属性并检查是否有注释 updatedEntityCode = Regex.Replace(updatedEntityCode, @"public (.+?) (.+?) \{ get; set; \}", match => { var propertyDeclaration = match.Value.Trim(); var itemPropertyCode = match.Groups[2].Value; if (itemDic.ContainsKey(itemPropertyCode)) { return $@" /// <summary> /// {itemDic[itemPropertyCode]} /// </summary> {propertyDeclaration}"; } return propertyDeclaration; // 已有注释则不修改 }); // 输出更新后的实体类代码 //Write(updatedEntityCode); // 写入更新后的实体类代码到同一文件中 File.WriteAllText(entityFile, updatedEntityCode); } #>
Remind
基于现有的DbContext文件,如果DbFirst生成结果有变化,需要重新调整正则
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!