背景:vs2017 、mysql数据库、T4模板、 安装了Devart T4 。
Devart T4 对T4模板进行高亮显示的编译器,支持T4调试。但是支持并不是特别好。创建ado数据模型后,自动生成的T4模板也会报错。。。不过聊胜于无。。。还是可以一用的
因为对T4模板的用法还是不是很了解,本着够用就好的原则,暂时不对这块深入学习。记录两种写法,备用
写法一:
1.来自创智博客黑马教程
2.使用<#@ include file="EF.Utility.CS.ttinclude"#>
3.写法比较简单
4.自行删除//后的内容
1 <#@ template language="C#" debug="false" hostspecific="true"#> 2 <#@ include file="EF.Utility.CS.ttinclude"#><#@ 3 output extension=".cs"#><# 4 5 string inputFile = @"..\\LingFeng.OA.Model\\DataModel.edmx"; //模型所在路径 6 CodeGenerationTools code = new CodeGenerationTools(this); 7 MetadataLoader loader= new MetadataLoader(this); 8 CodeRegion region = new CodeRegion(this); 9 MetadataTools ef = new MetadataTools(this); 10 11 EdmItemCollection ItemCollection =loader.CreateEdmItemCollection(inputFile); 12 string namespaceName=code.VsNamespaceSuggestion(); 13 EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this); 14 15 #> 16 using LingFeng.OA.Model;//需修改 17 18 namespace LingFeng.OA.IDal//需修改 19 { 20 <# 21 foreach(EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e=>e.Name)) 22 { 23 #> 24 public partial interface I<#=string.Concat(entity.Name.First<char>().ToString().ToUpper(),entity.Name.Substring(1))#>Dal: IBaseDal<<#=entity.Name#>>//此处应为mysql读到的模型都是小写,所以做了一个首字母转大写 25 { 26 27 } 28 <#}#> 29 }
写法二:
1.参考 DataModel.edmx 下 自动生成的的DataModel.tt的代码(谁让我完全不懂T4里的代码呢)
2.使用<#@ include file="EF6.Utility.CS.ttinclude"#>
3.保留 DataModel.tt 中定义的 public class TypeMapper
(在读取模型的时候用了这类的方法,因为看的不是很懂所以就全部保留这个类了,觉得代码多的,可以把类中的没用的方法删除)
4.保留 DataModel.tt 中定义的 public static void ArgumentNotNull<T>(T arg, string name) where T : class
(原因是EF6.Utility.CS.ttinclude 文件中调用了这个方法 ,但是没有定义?)
5.其他就容易了,代码比较长
6.自行删除//后的内容
ps: EF6.Utility.CS.ttinclude 和 EF.Utility.CS.ttinclude 的比较实用32位版本的 notepad++ (缩写npp) + compare 插件 (插件比较早,64位不能装这个插件)
上代码~
1 <#@ template language="C#" debug="false" hostspecific="true"#> 2 <#@ include file="EF6.Utility.CS.ttinclude"#><#@ 3 output extension=".cs"#><# 4 5 const string inputFile = @"..\\LingFeng.OA.Model\\DataModel.edmx"; 6 var textTransform = DynamicTextTransformation.Create(this); 7 var code = new CodeGenerationTools(this); 8 var ef = new MetadataTools(this); 9 var typeMapper = new TypeMapper(code, ef, textTransform.Errors); 10 var fileManager = EntityFrameworkTemplateFileManager.Create(this); 11 var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile); 12 13 14 if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile)) 15 { 16 return string.Empty; 17 } 18 19 #> 20 using LingFeng.OA.Model; 21 22 namespace LingFeng.OA.IDal 23 { 24 <# 25 foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection)) 26 {#> 27 public partial interface I<#=string.Concat(entity.Name.First<char>().ToString().ToUpper(),entity.Name.Substring(1))#>Dal: IBaseDal<<#=entity.Name#>> 28 { 29 30 }<# 31 }#> 32 33 } 34 <#+ 35 36 public class TypeMapper 37 { 38 private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; 39 40 private readonly System.Collections.IList _errors; 41 private readonly CodeGenerationTools _code; 42 private readonly MetadataTools _ef; 43 44 public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) 45 { 46 ArgumentNotNull(code, "code"); 47 ArgumentNotNull(ef, "ef"); 48 ArgumentNotNull(errors, "errors"); 49 50 _code = code; 51 _ef = ef; 52 _errors = errors; 53 } 54 55 public static string FixNamespaces(string typeName) 56 { 57 return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial."); 58 } 59 60 public string GetTypeName(TypeUsage typeUsage) 61 { 62 return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); 63 } 64 65 public string GetTypeName(EdmType edmType) 66 { 67 return GetTypeName(edmType, isNullable: null, modelNamespace: null); 68 } 69 70 public string GetTypeName(TypeUsage typeUsage, string modelNamespace) 71 { 72 return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); 73 } 74 75 public string GetTypeName(EdmType edmType, string modelNamespace) 76 { 77 return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); 78 } 79 80 public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) 81 { 82 if (edmType == null) 83 { 84 return null; 85 } 86 87 var collectionType = edmType as CollectionType; 88 if (collectionType != null) 89 { 90 return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); 91 } 92 93 var typeName = _code.Escape(edmType.MetadataProperties 94 .Where(p => p.Name == ExternalTypeNameAttributeName) 95 .Select(p => (string)p.Value) 96 .FirstOrDefault()) 97 ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? 98 _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : 99 _code.Escape(edmType)); 100 101 if (edmType is StructuralType) 102 { 103 return typeName; 104 } 105 106 if (edmType is SimpleType) 107 { 108 var clrType = UnderlyingClrType(edmType); 109 if (!IsEnumType(edmType)) 110 { 111 typeName = _code.Escape(clrType); 112 } 113 114 typeName = FixNamespaces(typeName); 115 116 return clrType.IsValueType && isNullable == true ? 117 String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : 118 typeName; 119 } 120 121 throw new ArgumentException("edmType"); 122 } 123 124 public Type UnderlyingClrType(EdmType edmType) 125 { 126 ArgumentNotNull(edmType, "edmType"); 127 128 var primitiveType = edmType as PrimitiveType; 129 if (primitiveType != null) 130 { 131 return primitiveType.ClrEquivalentType; 132 } 133 134 if (IsEnumType(edmType)) 135 { 136 return GetEnumUnderlyingType(edmType).ClrEquivalentType; 137 } 138 139 return typeof(object); 140 } 141 142 public object GetEnumMemberValue(MetadataItem enumMember) 143 { 144 ArgumentNotNull(enumMember, "enumMember"); 145 146 var valueProperty = enumMember.GetType().GetProperty("Value"); 147 return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); 148 } 149 150 public string GetEnumMemberName(MetadataItem enumMember) 151 { 152 ArgumentNotNull(enumMember, "enumMember"); 153 154 var nameProperty = enumMember.GetType().GetProperty("Name"); 155 return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); 156 } 157 158 public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) 159 { 160 ArgumentNotNull(enumType, "enumType"); 161 162 var membersProperty = enumType.GetType().GetProperty("Members"); 163 return membersProperty != null 164 ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) 165 : Enumerable.Empty<MetadataItem>(); 166 } 167 168 public bool EnumIsFlags(EdmType enumType) 169 { 170 ArgumentNotNull(enumType, "enumType"); 171 172 var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); 173 return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); 174 } 175 176 public bool IsEnumType(GlobalItem edmType) 177 { 178 ArgumentNotNull(edmType, "edmType"); 179 180 return edmType.GetType().Name == "EnumType"; 181 } 182 183 public PrimitiveType GetEnumUnderlyingType(EdmType enumType) 184 { 185 ArgumentNotNull(enumType, "enumType"); 186 187 return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); 188 } 189 190 public string CreateLiteral(object value) 191 { 192 if (value == null || value.GetType() != typeof(TimeSpan)) 193 { 194 return _code.CreateLiteral(value); 195 } 196 197 return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); 198 } 199 200 public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile) 201 { 202 ArgumentNotNull(types, "types"); 203 ArgumentNotNull(sourceFile, "sourceFile"); 204 205 var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); 206 if (types.Any(item => !hash.Add(item))) 207 { 208 _errors.Add( 209 new CompilerError(sourceFile, -1, -1, "6023", 210 String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict")))); 211 return false; 212 } 213 return true; 214 } 215 216 public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection) 217 { 218 return GetItemsToGenerate<SimpleType>(itemCollection) 219 .Where(e => IsEnumType(e)); 220 } 221 222 public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType 223 { 224 return itemCollection 225 .OfType<T>() 226 .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) 227 .OrderBy(i => i.Name); 228 } 229 230 public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection) 231 { 232 return itemCollection 233 .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) 234 .Select(g => GetGlobalItemName(g)); 235 } 236 237 public string GetGlobalItemName(GlobalItem item) 238 { 239 if (item is EdmType) 240 { 241 return ((EdmType)item).Name; 242 } 243 else 244 { 245 return ((EntityContainer)item).Name; 246 } 247 } 248 249 public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type) 250 { 251 return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); 252 } 253 254 public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type) 255 { 256 return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); 257 } 258 259 public IEnumerable<EdmProperty> GetComplexProperties(EntityType type) 260 { 261 return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); 262 } 263 264 public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type) 265 { 266 return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); 267 } 268 269 public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type) 270 { 271 return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); 272 } 273 274 public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type) 275 { 276 return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); 277 } 278 279 public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type) 280 { 281 return type.NavigationProperties.Where(np => np.DeclaringType == type); 282 } 283 284 public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type) 285 { 286 return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); 287 } 288 289 public FunctionParameter GetReturnParameter(EdmFunction edmFunction) 290 { 291 ArgumentNotNull(edmFunction, "edmFunction"); 292 293 var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); 294 return returnParamsProperty == null 295 ? edmFunction.ReturnParameter 296 : ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); 297 } 298 299 public bool IsComposable(EdmFunction edmFunction) 300 { 301 ArgumentNotNull(edmFunction, "edmFunction"); 302 303 var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); 304 return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); 305 } 306 307 public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction) 308 { 309 return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); 310 } 311 312 public TypeUsage GetReturnType(EdmFunction edmFunction) 313 { 314 var returnParam = GetReturnParameter(edmFunction); 315 return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); 316 } 317 318 public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) 319 { 320 var returnType = GetReturnType(edmFunction); 321 return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; 322 } 323 } 324 325 public static void ArgumentNotNull<T>(T arg, string name) where T : class 326 { 327 if (arg == null) 328 { 329 throw new ArgumentNullException(name); 330 } 331 } 332 #>