<#@ template debug="false" hostspecific="true" language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.IO" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Reflection" #> <#@ import namespace="System.ComponentModel" #> <#@ output extension=".cs" #> //------------------------------------------------------------------------------ // T4模板类:基础Map类 // 此代码由T4模板自动生成 // 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 //------------------------------------------------------------------------------ using APT.Infrastructure.EF.Map; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore; namespace APT.MS.Data.Mapping { <# List dlls=new List(); List filePaths=new List(); List tables = new List(); List modules=new List (); dlls.Add(Host.ResolveAssemblyReference("$(SolutionDir)"+"APT.MS.Domain\\")); dlls.Add(Host.ResolveAssemblyReference("$(SolutionDir)"+"APT.BaseData.Domain\\")); foreach(var dll in dlls){ GetFileName(filePaths,dll); } foreach(var p in filePaths) { var classText = File.ReadAllText(p, Encoding.UTF8); if (!string.IsNullOrEmpty(classText)) { int classTextIndex = 0; var space = GetElement(classText, "namespace", "{", ref classTextIndex); if (!string.IsNullOrEmpty(space)&& space.IndexOf("Domain.Entities", StringComparison.OrdinalIgnoreCase) > -1) { var classEleTxt = GetElement(classText, string.Empty, ":", ref classTextIndex); classTextIndex--; var baseClassTxt=GetElement(classText, ":", "{", ref classTextIndex); if (!string.IsNullOrEmpty(classEleTxt)) { TableT4 tableT4 = new TableT4(); tableT4.TableNameSpace = space; tableT4.BaseName = baseClassTxt; tableT4.BaseEntityName="APTEntityBaseMap"; if(tableT4.BaseName.IndexOf("TreeEntityBase<")>-1){ tableT4.BaseEntityName="TreeEntityBaseMap"; } tables.Add(tableT4); int classEleTxtIndex = 0; var attrTxt= GetElement(classEleTxt, "[", "]", ref classEleTxtIndex); while (!string.IsNullOrEmpty(attrTxt)) { if(attrTxt=="IgnoreT4") { tableT4.IgnoreT4=true; } tableT4.Attrs.Add(attrTxt); attrTxt = GetElement(classEleTxt, "[", "]", ref classEleTxtIndex); } if(tableT4.IgnoreT4) continue; var classEleTxt1 = GetElement(classEleTxt, "class", "", ref classEleTxtIndex); if (!string.IsNullOrEmpty(classEleTxt1)) tableT4.Name = classEleTxt1; var fieldEleTxt = GetElement(classText, string.Empty, "get", ref classTextIndex); while (!string.IsNullOrEmpty(fieldEleTxt)) { var tempFieldEleTxt = fieldEleTxt; var tempFieldEleIndex = 0; FieldT4 fieldT4 = new FieldT4(); tableT4.Fields.Add(fieldT4); var fieldAttrTxt = GetElement(tempFieldEleTxt, "[", "]", ref tempFieldEleIndex); while (!string.IsNullOrEmpty(fieldAttrTxt)) { fieldT4.Attrs.Add(fieldAttrTxt); fieldAttrTxt = GetElement(tempFieldEleTxt, "[", "]", ref tempFieldEleIndex); } var fieldEleTxt1 = GetElement(tempFieldEleTxt, "public", "{", ref tempFieldEleIndex); if (!string.IsNullOrEmpty(fieldEleTxt1)) { var fieldEles=fieldEleTxt1.Split(new char[] { ' ' },StringSplitOptions.RemoveEmptyEntries); if (fieldEles.Length > 0){ fieldT4.Name = fieldEles[fieldEles.Length - 1]; if (string.Compare(fieldEles[0], "String", true) == 0) { if (!fieldT4.Attrs.Any(t => t.StartsWith("DataFieldLength"))) fieldT4.Attrs.Add("DataFieldLength(500)"); } } } fieldEleTxt = GetElement(classText, "", "get", ref classTextIndex); } } } } } foreach(var t4 in tables) { if(t4.IgnoreT4) continue; var newName = t4.Name.ToLower(); var newNameAry = newName.Split(new char[] { '_' }); if (newNameAry.Any() && newNameAry.Length >= 2) { t4.ModuleName = newNameAry[1].ToUpper(); for (var n = 2; n < newNameAry.Length; n++) { t4.FixName += System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(newNameAry[n]); } } if(string.IsNullOrEmpty(t4.ModuleName)||string.IsNullOrEmpty(t4.FixName))continue; if(!modules.Any(i=>i==t4.TableNameSpace)){ modules.Add(t4.TableNameSpace); } if (t4.Attrs.Any()) { foreach(var classAttr in t4.Attrs) { if (classAttr.IndexOf("DataClassIndex", StringComparison.OrdinalIgnoreCase) > -1) { List indexFields = new List(); bool isUnique = false; var p1 = GetAttrParam(classAttr); int p1Index = 0; var indexStr = GetElement(p1, "{", "}", ref p1Index); if (!string.IsNullOrEmpty(indexStr)) indexFields.AddRange(indexStr.Split(new char[]{ ','})); var unqStr = GetElement(p1, ",", "", ref p1Index); isUnique = ToBoolean(unqStr); if (indexFields.Any()) t4.MapDatas.Add("builder.HasIndex(" + (string.Join(",", indexFields)) + ")" + (isUnique ? ".IsUnique()" : "") + ";"); } } } if (t4.Fields.Any()) { foreach(var f in t4.Fields) { if (!f.Attrs.Any()) continue; if (f.Attrs.Any(t => t.IndexOf("DataFieldIngore", StringComparison.OrdinalIgnoreCase) > -1)) { t4.MapDatas.Add("builder.Ignore(t => t." + f.Name + ");"); } else { foreach (var fAttr in f.Attrs) { if (fAttr.IndexOf("DataFieldLength", StringComparison.OrdinalIgnoreCase) > -1) { var p1 = GetAttrParams(fAttr); if (p1 != null && p1.Any()) t4.MapDatas.Add("builder.Property(t => t." + f.Name + ").HasMaxLength(" + p1[0] + ");"); } else if (fAttr.IndexOf("DataFieldIndex", StringComparison.OrdinalIgnoreCase) > -1) { var p1 = GetAttrParams(fAttr); bool isUnique = p1 != null && p1.Length > 0 ? ToBoolean(p1[0]) : false; if(isUnique){ string indexStr="builder.HasIndex(\""+ f.Name + "\""; for(var x=1;x -1) { var p1 = GetAttrParams(fAttr); if(p1!=null&& p1.Length>0) { var nav = p1[0]; var master = p1.Length > 1 ? p1[1] : string.Empty; var isOneOnOne=false; if(master=="true"||master=="false"){ isOneOnOne=bool.Parse(master); master=""; } if(p1.Length>2){ isOneOnOne=bool.Parse(p1[2]); } if(!isOneOnOne) { t4.MapDatas.Add("builder.HasOne(t => t." + nav + ").WithMany(" + (string.IsNullOrEmpty(master) ? "" : ("t=>t." + master)) + ").HasForeignKey(t => t." + f.Name + ").OnDelete(DeleteBehavior.Restrict);"); } else{ t4.MapDatas.Add("builder.HasOne(t => t." + nav + ").WithOne(" + (string.IsNullOrEmpty(master) ? "" : ("t=>t." + master)) + ").HasForeignKey<"+t4.Name+">(t => t." + f.Name + ").OnDelete(DeleteBehavior.Restrict);"); } } } else if (fAttr.IndexOf("UnionForeignKey", StringComparison.OrdinalIgnoreCase) > -1) { var p1 = GetAttrParams(fAttr); if(p1!=null&& p1.Length>0) { var forginkeys = p1[0].Split('|'); var forginkey = $"t.{string.Join(",t.", forginkeys)}"; var master = p1.Length > 1 ? p1[1] : string.Empty; t4.MapDatas.Add("builder.HasOne(t => t." + f.Name + ").WithMany(" + (string.IsNullOrEmpty(master) ? "" : ("t=>t." + master)) + ").HasForeignKey(t => new { " + forginkey + " });"); } } else if (fAttr.IndexOf("DataFieldForeignKeyForMaster", StringComparison.OrdinalIgnoreCase) > -1) { var p1 = GetAttrParams(fAttr); if (p1 != null && p1.Length > 0) { var id = p1[0]; var nav = p1.Length > 1 ? p1[1] : string.Empty; var isOneOnOne=false; if(nav=="true"||nav=="false"){ isOneOnOne=bool.Parse(nav); nav=""; } if(p1.Length>2){ isOneOnOne=bool.Parse(p1[2]); } if(!isOneOnOne) t4.MapDatas.Add("builder.HasMany(t => t." + f.Name + ").WithOne(" + (string.IsNullOrEmpty(nav) ? "" : ("t=>t." + nav)) + ").HasForeignKey(t => t." + id+ ").OnDelete(DeleteBehavior.Restrict);"); else t4.MapDatas.Add("builder.HasOne(t => t." + f.Name + ").WithOne(" + (string.IsNullOrEmpty(nav) ? "" : ("t=>t." + nav)) + ").HasForeignKey(t => t." + id+ ").OnDelete(DeleteBehavior.Restrict);"); } } } } } } } foreach(var space in modules) { WriteLine("using "+space +";"); } foreach(var t4 in tables) { if(string.IsNullOrEmpty(t4.ModuleName)||string.IsNullOrEmpty(t4.FixName)||t4.IgnoreT4)continue; #> #region <#= t4.FixName#> public partial class <#= t4.ModuleName#><#= t4.FixName#>Map :<#=t4.BaseEntityName#><<#= t4.Name#>> { public override void Configure(EntityTypeBuilder<<#= t4.Name#>> builder) { base.Configure(builder); <# if(t4.MapDatas.Any()) { foreach(var d in t4.MapDatas) { WriteLine(d); } } #> } } #endregion <#} #> } <#+ class TableT4 { public string TableNameSpace { get; set; } public string ModuleName { get; set; } public string FixName { get; set; } public string Name { get; set; } public string BaseName { get; set; } public string BaseEntityName{get;set;} public bool IgnoreT4{get;set;} public List Fields = new List(); public List MapDatas = new List(); public List Attrs = new List(); public TableT4() { MapDatas = new List(); Fields = new List(); Attrs = new List(); } } class FieldT4 { public FieldT4() { Attrs = new List(); } public string Name { get; set; } public List Attrs = new List(); } private static string GetElement(string txt,string startStr,string endStr, ref int index) { var tempStartIndex=string.IsNullOrEmpty(startStr)?index: txt.IndexOf(startStr, index, StringComparison.OrdinalIgnoreCase); var tempEndIndex = string.IsNullOrEmpty(endStr) ? txt.Length : txt.IndexOf(endStr, index, StringComparison.OrdinalIgnoreCase); if (tempStartIndex != -1&&tempEndIndex!=-1) { if (tempStartIndex > tempEndIndex) tempEndIndex = string.IsNullOrEmpty(endStr) ? txt.Length : txt.IndexOf(endStr, tempStartIndex , StringComparison.OrdinalIgnoreCase); var tempStartIndex1 = string.IsNullOrEmpty(startStr) ? -1 : txt.IndexOf(startStr, tempStartIndex+1, StringComparison.OrdinalIgnoreCase); if (tempStartIndex1 != -1&&tempStartIndex1< tempEndIndex) tempEndIndex = string.IsNullOrEmpty(endStr) ? txt.Length : txt.IndexOf(endStr, tempEndIndex+1, StringComparison.OrdinalIgnoreCase); int startStrLength = (string.IsNullOrEmpty(startStr) ? 0 : startStr.Length); int endStrLength = (string.IsNullOrEmpty(endStr) ? 0 : endStr.Length); index = tempEndIndex + endStrLength; string ret= txt.Substring(tempStartIndex+startStrLength, tempEndIndex-tempStartIndex- startStrLength); return ret.Trim(); } return string.Empty; } private static string GetAttrParam(string str) { int lefIndex = str.IndexOf("("); int rigthIndex = str.LastIndexOf(")"); if(lefIndex!=-1&&rigthIndex!=-1) { var ret= str.Substring(lefIndex + 1, rigthIndex - 1- lefIndex); return ret.Trim(); } return string.Empty; } private static string[] GetAttrParams(string str) { var ret = GetAttrParam(str); if (string.IsNullOrEmpty(ret)) return null; return ret.Split(',').Select(t => t.Trim().Replace("\"", "")).ToArray(); } private static bool ToBoolean(string str) { if (string.IsNullOrEmpty(str)) return false; try { return Convert.ToBoolean(str); }catch{ return false; } } public static void GetFileName(List filePaths, string path) { DirectoryInfo root = new DirectoryInfo(path); foreach (FileInfo f in root.GetFiles()) { if (f.Extension.ToLower()==".cs".ToLower()) { filePaths.Add(f.FullName); } } foreach (DirectoryInfo d in root.GetDirectories()) { GetFileName(filePaths, d.FullName); } } #>