精华内容
下载资源
问答
  • T4模板

    千次阅读 2016-04-30 15:45:52
    如何使用T4模板,比如我们在Model中添加了EF,这时候就会有T4模板。这个T4模板的名字就是....tt ,它的作用就是成类文件。假设我们现在需要在接口中类库中批量生成很多按照自己定义的接口类文件。那么我们就可以使用这...

    1

    T4模板的修改

     

    如何使用T4模板,比如我们在Model中添加了EF,这时候就会有T4模板。这个T4模板的名字就是....tt ,它的作用就是成类文件(当然这个类文件的内容是根据T4模板中的EntityClassOpening方法来生成的,我们可以根据这个方法里面的规则,来生成自己需要的内容。比如生成接口,或者生成类,等等)。假设我们现在需要在接口中类库中批量生成很多按照自己定义的接口类文件。那么我们就可以使用这个T4模板来批量生成。只需要将这个T4模板文件拷贝到接口类库中,并修改它的源代码即可

     比如,我要根据表名批量生成以下格式的接口类文件

    namespace FB.CMS.IRepository
    {
        using FB.CMS.Model;
        public interface ISysKeyValueRepository:IBaseDal<sysKeyValue>
        {
        }
    }

    具体做法就是修改T4模板的源文件。


    打开JKCRM.edmx文件下的JKCRM.tt 复制里面的内容到NotePad++中进行编辑

    <#@ template language="C#" debug="false" hostspecific="true"#>
    <#@ include file="EF.Utility.CS.ttinclude"#><#@ 
     output extension=".cs"#><#
    
    const string inputFile = @"JKCRM.edmx"; //特别要注意这里,如果你从FB.CMS.Model类库中复制这个T4模板到FB.CMS.FB.CMS.IRepository类库下,需要这里修改inputFile的值,例如在这里我们就修改成了const string inputFile = @"..\FB.CMS.Model\JKCRM.edmx";
    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);
    var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
    var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
    
    if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
    {
        return string.Empty;
    }
    
    WriteHeader(codeStringGenerator, fileManager); //开始写头文件
    
    foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
    {
        fileManager.StartNewFile(entity.Name + ".cs");
        BeginNamespace(code); //生成命名空间
    #>
    <#=codeStringGenerator.UsingDirectives(inHeader: false)#> //引用命名空间(如果我们想自己引用写其他的命名空间可以在这后面自己添加 如:using Model)
    //如果我们项目有需要引用其他的项目,可以在这里引用,例如可以这里就引用一个 using FB.CMS.Model;
    <#=codeStringGenerator.EntityClassOpening(entity)#> //生成类 (生成类的内容我们可以去EntityClassOpening方法中看)
    {
    <#
        var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
        var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
        var complexProperties = typeMapper.GetComplexProperties(entity);
    
        if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
        {
    #>
        public <#=code.Escape(entity)#>() //生成构造函数(不需要的话可以删除)
        {
    <#
            foreach (var edmProperty in propertiesWithDefaultValues)
            {
    #>
            this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
    <#
            }
    
            foreach (var navigationProperty in collectionNavigationProperties)
            {
    #>
            this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
    <#
            }
    
            foreach (var complexProperty in complexProperties)
            {
    #>
            this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
    <#
            }
    #>
        }
    
    <#
        }
    
        var simpleProperties = typeMapper.GetSimpleProperties(entity);
        if (simpleProperties.Any())
        {
            foreach (var edmProperty in simpleProperties)
            {
    #>
        <#=codeStringGenerator.Property(edmProperty)#> //生成属性的(不需要的话可以将这段输出删除)
    <#
            }
        }
    
        if (complexProperties.Any())
        {
    #>
    
    <#
            foreach(var complexProperty in complexProperties)
            {
    #>
        <#=codeStringGenerator.Property(complexProperty)#>  //生成复杂属性(不需要的话可以将这段输出删除)
    <#
            }
        }
    
        var navigationProperties = typeMapper.GetNavigationProperties(entity);
        if (navigationProperties.Any())
        {
    #>
    
    <#
            foreach (var navigationProperty in navigationProperties)
            {
    #>
        <#=codeStringGenerator.NavigationProperty(navigationProperty)#> //生成导航属性(不需要的话可以将这段输出删除)
    <#
            }
        }
    #>
    }
    <#
        EndNamespace(code);
    }
    
    foreach (var complex in typeMapper.GetItemsToGenerate<ComplexType>(itemCollection))
    {
        fileManager.StartNewFile(complex.Name + ".cs");
        BeginNamespace(code);
    #>
    <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
    <#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
    {
    <#
        var complexProperties = typeMapper.GetComplexProperties(complex);
        var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex);
    
        if (propertiesWithDefaultValues.Any() || complexProperties.Any())
        {
    #>
        public <#=code.Escape(complex)#>()
        {
    <#
            foreach (var edmProperty in propertiesWithDefaultValues)
            {
    #>
            this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
    <#
            }
    
            foreach (var complexProperty in complexProperties)
            {
    #>
            this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
    <#
            }
    #>
        }
    
    <#
        }
    
        var simpleProperties = typeMapper.GetSimpleProperties(complex);
        if (simpleProperties.Any())
        {
            foreach(var edmProperty in simpleProperties)
            {
    #>
        <#=codeStringGenerator.Property(edmProperty)#>
    <#
            }
        }
    
        if (complexProperties.Any())
        {
    #>
    
    <#
            foreach(var edmProperty in complexProperties)
            {
    #>
        <#=codeStringGenerator.Property(edmProperty)#>
    <#
            }
        }
    #>
    }
    <#
        EndNamespace(code);
    }
    
    foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection))
    {
        fileManager.StartNewFile(enumType.Name + ".cs");
        BeginNamespace(code);
    #>
    <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
    <#
        if (typeMapper.EnumIsFlags(enumType))
        {
    #>
    [Flags]
    <#
        }
    #>
    <#=codeStringGenerator.EnumOpening(enumType)#>
    {
    <#
        var foundOne = false;
        
        foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType))
        {
            foundOne = true;
    #>
        <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>,
    <#
        }
    
        if (foundOne)
        {
            this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1);
        }
    #>
    }
    <#
        EndNamespace(code);
    }
    
    fileManager.Process();
    
    #>
    <#+
    
    public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager)
    {
        fileManager.StartHeader();
    #>
    //------------------------------------------------------------------------------
    // <auto-generated>
    // <#=GetResourceString("Template_GeneratedCodeCommentLine1")#>
    //
    // <#=GetResourceString("Template_GeneratedCodeCommentLine2")#>
    // <#=GetResourceString("Template_GeneratedCodeCommentLine3")#>
    // </auto-generated>
    //------------------------------------------------------------------------------
    <#=codeStringGenerator.UsingDirectives(inHeader: true)#>
    <#+
        fileManager.EndBlock();
    }
    
    public void BeginNamespace(CodeGenerationTools code)
    {
        var codeNamespace = code.VsNamespaceSuggestion();
        if (!String.IsNullOrEmpty(codeNamespace))
        {
    #>
    namespace <#=code.EscapeNamespace(codeNamespace)#>
    {
    <#+
            PushIndent("    ");
        }
    }
    
    public void EndNamespace(CodeGenerationTools code)
    {
        if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion()))
        {
            PopIndent();
    #>
    }
    <#+
        }
    }
    
    public const string TemplateId = "CSharp_DbContext_Types_EF5";
    
    public class CodeStringGenerator
    {
        private readonly CodeGenerationTools _code;
        private readonly TypeMapper _typeMapper;
        private readonly MetadataTools _ef;
    
        public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
        {
            ArgumentNotNull(code, "code");
            ArgumentNotNull(typeMapper, "typeMapper");
            ArgumentNotNull(ef, "ef");
    
            _code = code;
            _typeMapper = typeMapper;
            _ef = ef;
        }
    
        public string Property(EdmProperty edmProperty)
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} {1} {2} {{ {3}get; {4}set; }}",
                Accessibility.ForProperty(edmProperty),
                _typeMapper.GetTypeName(edmProperty.TypeUsage),
                _code.Escape(edmProperty),
                _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
                _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
        }
    
        public string NavigationProperty(NavigationProperty navigationProperty)
        {
            var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType());
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} {1} {2} {{ {3}get; {4}set; }}",
                AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)),
                navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
                _code.Escape(navigationProperty),
                _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)),
                _code.SpaceAfter(Accessibility.ForSetter(navigationProperty)));
        }
        
        public string AccessibilityAndVirtual(string accessibility)
        {
            return accessibility + (accessibility != "private" ? " virtual" : "");
        }
        
        public string EntityClassOpening(EntityType entity)
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} {1}partial class {2}{3}",  //我们可以根据我们的需要来改;例如改成 "{0} {1}interface I{2}Repository:IBaseDal<{2}>", 就会生成一个接口的类文件,并且有生成了继承类
                Accessibility.ForType(entity), //这个对应的占位符是{0};他应该是生成访问修饰符,如public,private,internal,protected之类的
                _code.SpaceAfter(_code.AbstractOption(entity)),//这个对应的占位符是{1}; 它应该是生成override重写之类的关键词吧,具体不知道
                _code.Escape(entity), //这个对应的占位符是{2};这个应该是生成类名(其实就是表名称)
                _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); //这个对应的占位符是{3};这个应该是继承
        }
        
        public string EnumOpening(SimpleType enumType)
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} enum {1} : {2}",
                Accessibility.ForType(enumType),
                _code.Escape(enumType),
                _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
            }
        
        public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
        {
            var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
            foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
            {
                var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
                var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
                var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + parameter.RawClrTypeName + "))";
                writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
            }
        }
        
        public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
        {
            var parameters = _typeMapper.GetParameters(edmFunction);
            
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} IQueryable<{1}> {2}({3})",
                AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
                _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
                _code.Escape(edmFunction),
                string.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray()));
        }
        
        public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
        {
            var parameters = _typeMapper.GetParameters(edmFunction);
            
            return string.Format(
                CultureInfo.InvariantCulture,
                "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
                _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
                edmFunction.NamespaceName,
                edmFunction.Name,
                string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
                _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
        }
        
        public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
        {
            var parameters = _typeMapper.GetParameters(edmFunction);
            var returnType = _typeMapper.GetReturnType(edmFunction);
    
            var paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray());
            if (includeMergeOption)
            {
                paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
            }
    
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} {1} {2}({3})",
                AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
                returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
                _code.Escape(edmFunction),
                paramList);
        }
        
        public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
        {
            var parameters = _typeMapper.GetParameters(edmFunction);
            var returnType = _typeMapper.GetReturnType(edmFunction);
    
            var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
            if (includeMergeOption)
            {
                callParams = ", mergeOption" + callParams;
            }
            
            return string.Format(
                CultureInfo.InvariantCulture,
                "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
                returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
                edmFunction.Name,
                callParams);
        }
        
        public string DbSet(EntitySet entitySet)
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} DbSet<{1}> {2} {{ get; set; }}",
                Accessibility.ForReadOnlyProperty(entitySet),
                _typeMapper.GetTypeName(entitySet.ElementType),
                _code.Escape(entitySet));
        }
    
        public string UsingDirectives(bool inHeader, bool includeCollections = true)
        {
            return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
                ? string.Format(
                    CultureInfo.InvariantCulture,
                    "{0}using System;{1}" +
                    "{2}",
                    inHeader ? Environment.NewLine : "",
                    includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
                    inHeader ? "" : Environment.NewLine)
                : "";
        }
    }
    
    public class TypeMapper
    {
        private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
    
        private readonly System.Collections.IList _errors;
        private readonly CodeGenerationTools _code;
        private readonly MetadataTools _ef;
    
        public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
        {
            ArgumentNotNull(code, "code");
            ArgumentNotNull(ef, "ef");
            ArgumentNotNull(errors, "errors");
    
            _code = code;
            _ef = ef;
            _errors = errors;
        }
    
        public string GetTypeName(TypeUsage typeUsage)
        {
            return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
        }
    
        public string GetTypeName(EdmType edmType)
        {
            return GetTypeName(edmType, isNullable: null, modelNamespace: null);
        }
    
        public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
        {
            return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
        }
    
        public string GetTypeName(EdmType edmType, string modelNamespace)
        {
            return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
        }
    
        public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
        {
            if (edmType == null)
            {
                return null;
            }
    
            var collectionType = edmType as CollectionType;
            if (collectionType != null)
            {
                return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
            }
    
            var typeName = _code.Escape(edmType.MetadataProperties
                                    .Where(p => p.Name == ExternalTypeNameAttributeName)
                                    .Select(p => (string)p.Value)
                                    .FirstOrDefault())
                ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
                    _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
                    _code.Escape(edmType));
    
            if (edmType is StructuralType)
            {
                return typeName;
            }
    
            if (edmType is SimpleType)
            {
                var clrType = UnderlyingClrType(edmType);
                if (!IsEnumType(edmType))
                {
                    typeName = _code.Escape(clrType);
                }
    
                return clrType.IsValueType && isNullable == true ?
                    String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
                    typeName;
            }
    
            throw new ArgumentException("edmType");
        }
        
        public Type UnderlyingClrType(EdmType edmType)
        {
            ArgumentNotNull(edmType, "edmType");
    
            var primitiveType = edmType as PrimitiveType;
            if (primitiveType != null)
            {
                return primitiveType.ClrEquivalentType;
            }
    
            if (IsEnumType(edmType))
            {
                return GetEnumUnderlyingType(edmType).ClrEquivalentType;
            }
    
            return typeof(object);
        }
        
        public object GetEnumMemberValue(MetadataItem enumMember)
        {
            ArgumentNotNull(enumMember, "enumMember");
            
            var valueProperty = enumMember.GetType().GetProperty("Value");
            return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
        }
        
        public string GetEnumMemberName(MetadataItem enumMember)
        {
            ArgumentNotNull(enumMember, "enumMember");
            
            var nameProperty = enumMember.GetType().GetProperty("Name");
            return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
        }
    
        public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
        {
            ArgumentNotNull(enumType, "enumType");
    
            var membersProperty = enumType.GetType().GetProperty("Members");
            return membersProperty != null 
                ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
                : Enumerable.Empty<MetadataItem>();
        }
        
        public bool EnumIsFlags(EdmType enumType)
        {
            ArgumentNotNull(enumType, "enumType");
            
            var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
            return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
        }
    
        public bool IsEnumType(GlobalItem edmType)
        {
            ArgumentNotNull(edmType, "edmType");
    
            return edmType.GetType().Name == "EnumType";
        }
    
        public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
        {
            ArgumentNotNull(enumType, "enumType");
    
            return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
        }
    
        public string CreateLiteral(object value)
        {
            if (value == null || value.GetType() != typeof(TimeSpan))
            {
                return _code.CreateLiteral(value);
            }
    
            return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
        }
        
        public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
        {
            ArgumentNotNull(types, "types");
            ArgumentNotNull(sourceFile, "sourceFile");
            
            var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
            if (types.Any(item => !hash.Add(item)))
            {
                _errors.Add(
                    new CompilerError(sourceFile, -1, -1, "6023",
                        String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict"))));
                return false;
            }
            return true;
        }
        
        public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
        {
            return GetItemsToGenerate<SimpleType>(itemCollection)
                .Where(e => IsEnumType(e));
        }
        
        public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
        {
            return itemCollection
                .OfType<T>()
                .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
                .OrderBy(i => i.Name);
        }
    
        public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
        {
            return itemCollection
                .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
                .Select(g => GetGlobalItemName(g));
        }
    
        public string GetGlobalItemName(GlobalItem item)
        {
            if (item is EdmType)
            {
                return ((EdmType)item).Name;
            }
            else
            {
                return ((EntityContainer)item).Name;
            }
        }
    
        public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
        {
            return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
        }
        
        public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
        {
            return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
        }
        
        public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
        {
            return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
        }
        
        public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
        {
            return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
        }
    
        public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
        {
            return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
        }
        
        public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
        {
            return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
        }
    
        public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
        {
            return type.NavigationProperties.Where(np => np.DeclaringType == type);
        }
        
        public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
        {
            return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
        }
        
        public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
        {
            ArgumentNotNull(edmFunction, "edmFunction");
    
            var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
            return returnParamsProperty == null
                ? edmFunction.ReturnParameter
                : ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
        }
    
        public bool IsComposable(EdmFunction edmFunction)
        {
            ArgumentNotNull(edmFunction, "edmFunction");
    
            var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
            return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
        }
    
        public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
        {
            return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
        }
    
        public TypeUsage GetReturnType(EdmFunction edmFunction)
        {
            var returnParam = GetReturnParameter(edmFunction);
            return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
        }
        
        public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
        {
            var returnType = GetReturnType(edmFunction);
            return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
        }
    }
    
    public class EdmMetadataLoader
    {
        private readonly IDynamicHost _host;
        private readonly System.Collections.IList _errors;
    
        public EdmMetadataLoader(IDynamicHost host, System.Collections.IList errors)
        {
            ArgumentNotNull(host, "host");
            ArgumentNotNull(errors, "errors");
    
            _host = host;
            _errors = errors;
        }
    
        public IEnumerable<GlobalItem> CreateEdmItemCollection(string sourcePath)
        {
            ArgumentNotNull(sourcePath, "sourcePath");
    
            if (!ValidateInputPath(sourcePath))
            {
                return new EdmItemCollection();
            }
    
            var schemaElement = LoadRootElement(_host.ResolvePath(sourcePath));
            if (schemaElement != null)
            {
                using (var reader = schemaElement.CreateReader())
                {
                    IList<EdmSchemaError> errors;
                    var itemCollection = MetadataItemCollectionFactory.CreateEdmItemCollection(new[] { reader }, out errors);
    
                    ProcessErrors(errors, sourcePath);
    
                    return itemCollection;
                }
            }
            return new EdmItemCollection();
        }
    
        public string GetModelNamespace(string sourcePath)
        {
            ArgumentNotNull(sourcePath, "sourcePath");
    
            if (!ValidateInputPath(sourcePath))
            {
                return string.Empty;
            }
    
            var model = LoadRootElement(_host.ResolvePath(sourcePath));
            if (model == null)
            {
                return string.Empty;
            }
    
            var attribute = model.Attribute("Namespace");
            return attribute != null ? attribute.Value : "";
        }
    
        private bool ValidateInputPath(string sourcePath)
        {
            if (sourcePath == "$" + "edmxInputFile" + "$")
            {
                _errors.Add(
                    new CompilerError(_host.TemplateFile ?? sourcePath, 0, 0, string.Empty,
                        GetResourceString("Template_ReplaceVsItemTemplateToken")));
                return false;
            }
    
            return true;
        }
    
        public XElement LoadRootElement(string sourcePath)
        {
            ArgumentNotNull(sourcePath, "sourcePath");
    
            var root = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);
            return root.Elements()
                .Where(e => e.Name.LocalName == "Runtime")
                .Elements()
                .Where(e => e.Name.LocalName == "ConceptualModels")
                .Elements()
                .Where(e => e.Name.LocalName == "Schema")
                .FirstOrDefault()
                    ?? root;
        }
    
        private void ProcessErrors(IEnumerable<EdmSchemaError> errors, string sourceFilePath)
        {
            foreach (var error in errors)
            {
                _errors.Add(
                    new CompilerError(
                        error.SchemaLocation ?? sourceFilePath,
                        error.Line,
                        error.Column,
                        error.ErrorCode.ToString(CultureInfo.InvariantCulture),
                        error.Message)
                    {
                        IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning
                    });
            }
        }
        
        public bool IsLazyLoadingEnabled(EntityContainer container)
        {
            string lazyLoadingAttributeValue;
            var lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled";
            bool isLazyLoading;
            return !MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue)
                || !bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading)
                || isLazyLoading;
        }
    }
    
    public static void ArgumentNotNull<T>(T arg, string name) where T : class
    {
        if (arg == null)
        {
            throw new ArgumentNullException(name);
        }
    }
        
    private static readonly Lazy<System.Resources.ResourceManager> ResourceManager =
        new Lazy<System.Resources.ResourceManager>(
            () => new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(MetadataItemCollectionFactory).Assembly), isThreadSafe: true);
    
    public static string GetResourceString(string resourceName)
    {
        ArgumentNotNull(resourceName, "resourceName");
    
        return ResourceManager.Value.GetString(resourceName, null);
    }
    
    #>
    

    以下是我自己修改的内容,看修改后生成的文件是什么样的;

    添加了一个using FB.CMS.Model;引用,删除了构造函数,禁止生成普通属性,禁止生成复杂属性和禁止生成导航属性。

    并对EntityClassOpening方法的内容进行了修改。具体可以与上面做一个对比。

    <#@ template language="C#" debug="false" hostspecific="true"#>
    <#@ include file="EF.Utility.CS.ttinclude"#><#@ 
     output extension=".cs"#><#
    
    const string inputFile = @"..\FB.CMS.Model\JKCRM.edmx";
    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);
    var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
    var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
    
    if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
    {
        return string.Empty;
    }
    
    WriteHeader(codeStringGenerator, fileManager);
    
    foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
    {
        fileManager.StartNewFile(entity.Name + ".cs");
        BeginNamespace(code);
    #>
    <#=codeStringGenerator.UsingDirectives(inHeader: false)#>
    using FB.CMS.Model;
    <#=codeStringGenerator.EntityClassOpening(entity)#>
    {
    <#
        var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
        var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
        var complexProperties = typeMapper.GetComplexProperties(entity);
    
        if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
        {
    #>
       
    
    <#
        }
    
        var simpleProperties = typeMapper.GetSimpleProperties(entity);
        if (simpleProperties.Any())
        {
            foreach (var edmProperty in simpleProperties)
            {
    #>
      
    <#
            }
        }
    
        if (complexProperties.Any())
        {
    #>
    
    <#
            foreach(var complexProperty in complexProperties)
            {
    #>
     
    <#
            }
        }
    
        var navigationProperties = typeMapper.GetNavigationProperties(entity);
        if (navigationProperties.Any())
        {
    #>
    
    <#
            foreach (var navigationProperty in navigationProperties)
            {
    #>
       
    <#
            }
        }
    #>
    }
    <#
        EndNamespace(code);
    }
    
    foreach (var complex in typeMapper.GetItemsToGenerate<ComplexType>(itemCollection))
    {
        fileManager.StartNewFile(complex.Name + ".cs");
        BeginNamespace(code);
    #>
    <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
    <#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
    {
    <#
        var complexProperties = typeMapper.GetComplexProperties(complex);
        var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex);
    
        if (propertiesWithDefaultValues.Any() || complexProperties.Any())
        {
    #>
        public <#=code.Escape(complex)#>()
        {
    <#
            foreach (var edmProperty in propertiesWithDefaultValues)
            {
    #>
            this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
    <#
            }
    
            foreach (var complexProperty in complexProperties)
            {
    #>
            this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
    <#
            }
    #>
        }
    
    <#
        }
    
        var simpleProperties = typeMapper.GetSimpleProperties(complex);
        if (simpleProperties.Any())
        {
            foreach(var edmProperty in simpleProperties)
            {
    #>
        <#=codeStringGenerator.Property(edmProperty)#>
    <#
            }
        }
    
        if (complexProperties.Any())
        {
    #>
    
    <#
            foreach(var edmProperty in complexProperties)
            {
    #>
        <#=codeStringGenerator.Property(edmProperty)#>
    <#
            }
        }
    #>
    }
    <#
        EndNamespace(code);
    }
    
    foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection))
    {
        fileManager.StartNewFile(enumType.Name + ".cs");
        BeginNamespace(code);
    #>
    <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
    <#
        if (typeMapper.EnumIsFlags(enumType))
        {
    #>
    [Flags]
    <#
        }
    #>
    <#=codeStringGenerator.EnumOpening(enumType)#>
    {
    <#
        var foundOne = false;
        
        foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType))
        {
            foundOne = true;
    #>
        <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>,
    <#
        }
    
        if (foundOne)
        {
            this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1);
        }
    #>
    }
    <#
        EndNamespace(code);
    }
    
    fileManager.Process();
    
    #>
    <#+
    
    public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager)
    {
        fileManager.StartHeader();
    #>
    //------------------------------------------------------------------------------
    // <auto-generated>
    // <#=GetResourceString("Template_GeneratedCodeCommentLine1")#>
    //
    // <#=GetResourceString("Template_GeneratedCodeCommentLine2")#>
    // <#=GetResourceString("Template_GeneratedCodeCommentLine3")#>
    // </auto-generated>
    //------------------------------------------------------------------------------
    <#=codeStringGenerator.UsingDirectives(inHeader: true)#>
    <#+
        fileManager.EndBlock();
    }
    
    public void BeginNamespace(CodeGenerationTools code)
    {
        var codeNamespace = code.VsNamespaceSuggestion();
        if (!String.IsNullOrEmpty(codeNamespace))
        {
    #>
    namespace <#=code.EscapeNamespace(codeNamespace)#>
    {
    <#+
            PushIndent("    ");
        }
    }
    
    public void EndNamespace(CodeGenerationTools code)
    {
        if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion()))
        {
            PopIndent();
    #>
    }
    <#+
        }
    }
    
    public const string TemplateId = "CSharp_DbContext_Types_EF5";
    
    public class CodeStringGenerator
    {
        private readonly CodeGenerationTools _code;
        private readonly TypeMapper _typeMapper;
        private readonly MetadataTools _ef;
    
        public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
        {
            ArgumentNotNull(code, "code");
            ArgumentNotNull(typeMapper, "typeMapper");
            ArgumentNotNull(ef, "ef");
    
            _code = code;
            _typeMapper = typeMapper;
            _ef = ef;
        }
    
        public string Property(EdmProperty edmProperty)
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} {1} {2} {{ {3}get; {4}set; }}",
                Accessibility.ForProperty(edmProperty),
                _typeMapper.GetTypeName(edmProperty.TypeUsage),
                _code.Escape(edmProperty),
                _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
                _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
        }
    
        public string NavigationProperty(NavigationProperty navigationProperty)
        {
            var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType());
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} {1} {2} {{ {3}get; {4}set; }}",
                AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)),
                navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
                _code.Escape(navigationProperty),
                _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)),
                _code.SpaceAfter(Accessibility.ForSetter(navigationProperty)));
        }
        
        public string AccessibilityAndVirtual(string accessibility)
        {
            return accessibility + (accessibility != "private" ? " virtual" : "");
        }
        
        public string EntityClassOpening(EntityType entity)
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} {1}interface I{2}Repository:IBaseDal<{2}>",
                Accessibility.ForType(entity),
                _code.SpaceAfter(_code.AbstractOption(entity)),
                _code.Escape(entity),
                _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
        }
        
        public string EnumOpening(SimpleType enumType)
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} enum {1} : {2}",
                Accessibility.ForType(enumType),
                _code.Escape(enumType),
                _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
            }
        
        public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
        {
            var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
            foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
            {
                var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
                var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
                var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + parameter.RawClrTypeName + "))";
                writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
            }
        }
        
        public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
        {
            var parameters = _typeMapper.GetParameters(edmFunction);
            
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} IQueryable<{1}> {2}({3})",
                AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
                _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
                _code.Escape(edmFunction),
                string.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray()));
        }
        
        public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
        {
            var parameters = _typeMapper.GetParameters(edmFunction);
            
            return string.Format(
                CultureInfo.InvariantCulture,
                "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
                _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
                edmFunction.NamespaceName,
                edmFunction.Name,
                string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
                _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
        }
        
        public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
        {
            var parameters = _typeMapper.GetParameters(edmFunction);
            var returnType = _typeMapper.GetReturnType(edmFunction);
    
            var paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray());
            if (includeMergeOption)
            {
                paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
            }
    
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} {1} {2}({3})",
                AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
                returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
                _code.Escape(edmFunction),
                paramList);
        }
        
        public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
        {
            var parameters = _typeMapper.GetParameters(edmFunction);
            var returnType = _typeMapper.GetReturnType(edmFunction);
    
            var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
            if (includeMergeOption)
            {
                callParams = ", mergeOption" + callParams;
            }
            
            return string.Format(
                CultureInfo.InvariantCulture,
                "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
                returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
                edmFunction.Name,
                callParams);
        }
        
        public string DbSet(EntitySet entitySet)
        {
            return string.Format(
                CultureInfo.InvariantCulture,
                "{0} DbSet<{1}> {2} {{ get; set; }}",
                Accessibility.ForReadOnlyProperty(entitySet),
                _typeMapper.GetTypeName(entitySet.ElementType),
                _code.Escape(entitySet));
        }
    
        public string UsingDirectives(bool inHeader, bool includeCollections = true)
        {
            return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
                ? string.Format(
                    CultureInfo.InvariantCulture,
                    "{0}using System;{1}" +
                    "{2}",
                    inHeader ? Environment.NewLine : "",
                    includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
                    inHeader ? "" : Environment.NewLine)
                : "";
        }
    }
    
    public class TypeMapper
    {
        private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
    
        private readonly System.Collections.IList _errors;
        private readonly CodeGenerationTools _code;
        private readonly MetadataTools _ef;
    
        public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
        {
            ArgumentNotNull(code, "code");
            ArgumentNotNull(ef, "ef");
            ArgumentNotNull(errors, "errors");
    
            _code = code;
            _ef = ef;
            _errors = errors;
        }
    
        public string GetTypeName(TypeUsage typeUsage)
        {
            return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
        }
    
        public string GetTypeName(EdmType edmType)
        {
            return GetTypeName(edmType, isNullable: null, modelNamespace: null);
        }
    
        public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
        {
            return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
        }
    
        public string GetTypeName(EdmType edmType, string modelNamespace)
        {
            return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
        }
    
        public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
        {
            if (edmType == null)
            {
                return null;
            }
    
            var collectionType = edmType as CollectionType;
            if (collectionType != null)
            {
                return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
            }
    
            var typeName = _code.Escape(edmType.MetadataProperties
                                    .Where(p => p.Name == ExternalTypeNameAttributeName)
                                    .Select(p => (string)p.Value)
                                    .FirstOrDefault())
                ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
                    _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
                    _code.Escape(edmType));
    
            if (edmType is StructuralType)
            {
                return typeName;
            }
    
            if (edmType is SimpleType)
            {
                var clrType = UnderlyingClrType(edmType);
                if (!IsEnumType(edmType))
                {
                    typeName = _code.Escape(clrType);
                }
    
                return clrType.IsValueType && isNullable == true ?
                    String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
                    typeName;
            }
    
            throw new ArgumentException("edmType");
        }
        
        public Type UnderlyingClrType(EdmType edmType)
        {
            ArgumentNotNull(edmType, "edmType");
    
            var primitiveType = edmType as PrimitiveType;
            if (primitiveType != null)
            {
                return primitiveType.ClrEquivalentType;
            }
    
            if (IsEnumType(edmType))
            {
                return GetEnumUnderlyingType(edmType).ClrEquivalentType;
            }
    
            return typeof(object);
        }
        
        public object GetEnumMemberValue(MetadataItem enumMember)
        {
            ArgumentNotNull(enumMember, "enumMember");
            
            var valueProperty = enumMember.GetType().GetProperty("Value");
            return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
        }
        
        public string GetEnumMemberName(MetadataItem enumMember)
        {
            ArgumentNotNull(enumMember, "enumMember");
            
            var nameProperty = enumMember.GetType().GetProperty("Name");
            return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
        }
    
        public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
        {
            ArgumentNotNull(enumType, "enumType");
    
            var membersProperty = enumType.GetType().GetProperty("Members");
            return membersProperty != null 
                ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
                : Enumerable.Empty<MetadataItem>();
        }
        
        public bool EnumIsFlags(EdmType enumType)
        {
            ArgumentNotNull(enumType, "enumType");
            
            var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
            return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
        }
    
        public bool IsEnumType(GlobalItem edmType)
        {
            ArgumentNotNull(edmType, "edmType");
    
            return edmType.GetType().Name == "EnumType";
        }
    
        public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
        {
            ArgumentNotNull(enumType, "enumType");
    
            return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
        }
    
        public string CreateLiteral(object value)
        {
            if (value == null || value.GetType() != typeof(TimeSpan))
            {
                return _code.CreateLiteral(value);
            }
    
            return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
        }
        
        public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
        {
            ArgumentNotNull(types, "types");
            ArgumentNotNull(sourceFile, "sourceFile");
            
            var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
            if (types.Any(item => !hash.Add(item)))
            {
                _errors.Add(
                    new CompilerError(sourceFile, -1, -1, "6023",
                        String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict"))));
                return false;
            }
            return true;
        }
        
        public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
        {
            return GetItemsToGenerate<SimpleType>(itemCollection)
                .Where(e => IsEnumType(e));
        }
        
        public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
        {
            return itemCollection
                .OfType<T>()
                .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
                .OrderBy(i => i.Name);
        }
    
        public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
        {
            return itemCollection
                .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
                .Select(g => GetGlobalItemName(g));
        }
    
        public string GetGlobalItemName(GlobalItem item)
        {
            if (item is EdmType)
            {
                return ((EdmType)item).Name;
            }
            else
            {
                return ((EntityContainer)item).Name;
            }
        }
    
        public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
        {
            return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
        }
        
        public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
        {
            return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
        }
        
        public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
        {
            return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
        }
        
        public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
        {
            return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
        }
    
        public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
        {
            return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
        }
        
        public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
        {
            return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
        }
    
        public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
        {
            return type.NavigationProperties.Where(np => np.DeclaringType == type);
        }
        
        public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
        {
            return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
        }
        
        public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
        {
            ArgumentNotNull(edmFunction, "edmFunction");
    
            var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
            return returnParamsProperty == null
                ? edmFunction.ReturnParameter
                : ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
        }
    
        public bool IsComposable(EdmFunction edmFunction)
        {
            ArgumentNotNull(edmFunction, "edmFunction");
    
            var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
            return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
        }
    
        public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
        {
            return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
        }
    
        public TypeUsage GetReturnType(EdmFunction edmFunction)
        {
            var returnParam = GetReturnParameter(edmFunction);
            return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
        }
        
        public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
        {
            var returnType = GetReturnType(edmFunction);
            return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
        }
    }
    
    public class EdmMetadataLoader
    {
        private readonly IDynamicHost _host;
        private readonly System.Collections.IList _errors;
    
        public EdmMetadataLoader(IDynamicHost host, System.Collections.IList errors)
        {
            ArgumentNotNull(host, "host");
            ArgumentNotNull(errors, "errors");
    
            _host = host;
            _errors = errors;
        }
    
        public IEnumerable<GlobalItem> CreateEdmItemCollection(string sourcePath)
        {
            ArgumentNotNull(sourcePath, "sourcePath");
    
            if (!ValidateInputPath(sourcePath))
            {
                return new EdmItemCollection();
            }
    
            var schemaElement = LoadRootElement(_host.ResolvePath(sourcePath));
            if (schemaElement != null)
            {
                using (var reader = schemaElement.CreateReader())
                {
                    IList<EdmSchemaError> errors;
                    var itemCollection = MetadataItemCollectionFactory.CreateEdmItemCollection(new[] { reader }, out errors);
    
                    ProcessErrors(errors, sourcePath);
    
                    return itemCollection;
                }
            }
            return new EdmItemCollection();
        }
    
        public string GetModelNamespace(string sourcePath)
        {
            ArgumentNotNull(sourcePath, "sourcePath");
    
            if (!ValidateInputPath(sourcePath))
            {
                return string.Empty;
            }
    
            var model = LoadRootElement(_host.ResolvePath(sourcePath));
            if (model == null)
            {
                return string.Empty;
            }
    
            var attribute = model.Attribute("Namespace");
            return attribute != null ? attribute.Value : "";
        }
    
        private bool ValidateInputPath(string sourcePath)
        {
            if (sourcePath == "$" + "edmxInputFile" + "$")
            {
                _errors.Add(
                    new CompilerError(_host.TemplateFile ?? sourcePath, 0, 0, string.Empty,
                        GetResourceString("Template_ReplaceVsItemTemplateToken")));
                return false;
            }
    
            return true;
        }
    
        public XElement LoadRootElement(string sourcePath)
        {
            ArgumentNotNull(sourcePath, "sourcePath");
    
            var root = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);
            return root.Elements()
                .Where(e => e.Name.LocalName == "Runtime")
                .Elements()
                .Where(e => e.Name.LocalName == "ConceptualModels")
                .Elements()
                .Where(e => e.Name.LocalName == "Schema")
                .FirstOrDefault()
                    ?? root;
        }
    
        private void ProcessErrors(IEnumerable<EdmSchemaError> errors, string sourceFilePath)
        {
            foreach (var error in errors)
            {
                _errors.Add(
                    new CompilerError(
                        error.SchemaLocation ?? sourceFilePath,
                        error.Line,
                        error.Column,
                        error.ErrorCode.ToString(CultureInfo.InvariantCulture),
                        error.Message)
                    {
                        IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning
                    });
            }
        }
        
        public bool IsLazyLoadingEnabled(EntityContainer container)
        {
            string lazyLoadingAttributeValue;
            var lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled";
            bool isLazyLoading;
            return !MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue)
                || !bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading)
                || isLazyLoading;
        }
    }
    
    public static void ArgumentNotNull<T>(T arg, string name) where T : class
    {
        if (arg == null)
        {
            throw new ArgumentNullException(name);
        }
    }
        
    private static readonly Lazy<System.Resources.ResourceManager> ResourceManager =
        new Lazy<System.Resources.ResourceManager>(
            () => new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(MetadataItemCollectionFactory).Assembly), isThreadSafe: true);
    
    public static string GetResourceString(string resourceName)
    {
        ArgumentNotNull(resourceName, "resourceName");
    
        return ResourceManager.Value.GetString(resourceName, null);
    }
    
    #>

    通过以上修改就生成了以下


    那我们随便打开一个sysKeyValue.cs文件,看看它的内容具体是怎样的? 打开sysKeyValue.cs发现它的内容是以下内容

    //------------------------------------------------------------------------------
    // <auto-generated>
    //    此代码是根据模板生成的。
    //
    //    手动更改此文件可能会导致应用程序中发生异常行为。
    //    如果重新生成代码,则将覆盖对此文件的手动更改。
    // </auto-generated>
    //------------------------------------------------------------------------------
    
    namespace FB.CMS.IRepository
    {
        using System;
        using System.Collections.Generic;
        
        using FB.CMS.Model;
        public interface IsysKeyValueRepository:IBaseDal<sysKeyValue>
        {
           
        
          
          
          
          
          
        
           
           
           
           
           
           
           
        }
    }
    


    特别注意这个T4模板只能用于第一次生成。如果你需要的接口(类)文件都生成了。那么我们就应该将这个T4模板删除,如果不移删除,万一哪天不小心打开了,然后一保存,它又会重新生生成一次,于是就将之前生成的文件覆盖掉。所以为了保险起见,我们利用T4模板生成了我们需要的接口(类)文件后就应该将它删除,当然我们可以将这个T4模板文件一到一个安全的地方保存起来,以便下来使用。


    关于复杂属性,与导航属性的修改

    <#@ template language="C#" debug="false" hostspecific="true"#>
    <#@ include file="EF.Utility.CS.ttinclude"#><#@ 
     output extension=".cs"#><#
    
    const string inputFile = @"..\JKCRM.edmx";
    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);
    var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
    var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
    
    if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
    {
        return string.Empty;
    }
    
    WriteHeader(codeStringGenerator, fileManager);
    
    foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
    {
        fileManager.StartNewFile(entity.Name + ".cs");
        BeginNamespace(code);
    #>
    <#=codeStringGenerator.UsingDirectives(inHeader: false)#>
    <#=codeStringGenerator.EntityClassOpening(entity)#>
    {
    <#
        var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
        var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
        var complexProperties = typeMapper.GetComplexProperties(entity);
    
        if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
        {
    #>
       
    
    <#
        }
    
        var simpleProperties = typeMapper.GetSimpleProperties(entity);
        if (simpleProperties.Any())
        {
            foreach (var edmProperty in simpleProperties)
            {
    #>
        <#=codeStringGenerator.Property(edmProperty)#> //这里是输出普通属性
    <#
            }
        }
    
        if (complexProperties.Any())
        {
    #>
    
    <#
            foreach(var complexProperty in complexProperties)
            {
    #>
        <#=codeStringGenerator.Property(complexProperty)#> //这里是输出复杂属性(多对一)
    <#
            }
        }
    
        var navigationProperties = typeMapper.GetNavigationProperties(entity);
        if (navigationProperties.Any())
        {
    #>
    
    <#
            foreach (var navigationProperty in navigationProperties)
            {
    #>
        <#=codeStringGenerator.NavigationProperty(navigationProperty)#> //这里是输出导航属性(一对多)
    <#
            }
        }
    #>
    }
    <#
        EndNamespace(code);
    }
    
        //........................为了强调复杂属性与导航属性的修改。多余的东西我暂时删除掉了
    
    
    //复杂属性与导航属性就在这个方法中修改
    public string NavigationProperty(NavigationProperty navigationProperty)
    {
        var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType());
        return string.Format(
            CultureInfo.InvariantCulture,
            "{0} {1} {2} {{ {3}get; {4}set; }}",
            AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)),
    		
    		//只要在这修改就可以了。("ICollection<" + endType + "View"+">") 是修改导航属性的类型的 ,后面这个View是我自己加上去的。假设之前的导航属性类型为sysMenus,经过这么一加,导航属性的类型就变为sysMenusView类型了(这个enType其实就是表名,应该说是类名,只是我们这里需要改类名)
    		//例如:没有修改前,导航属性是这样的:public virtual ICollection<sysPermissList> sysPermissList { get; set; }
    		//进过修过后,导航属性就变成这样了:public virtual ICollection<sysPermissListView> sysPermissList { get; set; }
    		
    		//: endType+"View"是修改复杂属性的类型的;endType+"View"后面这个View也是我自己加的;假设之前的复杂属性的类型为sysMenus,经过这么一加,复杂属性的的类型就变为sysMenusView类型了
    		//例如:没有修改前复杂属性是这样的:public virtual sysMenus sysMenus { get; set; }
    		//经过修改后,复杂属性变成这样了:public virtual sysMenusView sysMenus { get; set; }
            navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + "View"+">") : endType+"View",
            _code.Escape(navigationProperty),
            _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)),
            _code.SpaceAfter(Accessibility.ForSetter(navigationProperty)));
    }
        
       
        
        
    通过以上修改,生成的文件如下:
    //------------------------------------------------------------------------------
    // <auto-generated>
    //    此代码是根据模板生成的。
    //
    //    手动更改此文件可能会导致应用程序中发生异常行为。
    //    如果重新生成代码,则将覆盖对此文件的手动更改。
    // </auto-generated>
    //------------------------------------------------------------------------------
    
    namespace FB.CMS.Model.ModelView
    {
        using System;
        using System.Collections.Generic;
        
        public  class sysFunctionView
        {
           
        
            public int fID { get; set; }
            public int mID { get; set; }
            public string fName { get; set; }
            public string fFunction { get; set; }
            public string fPicname { get; set; }
            public Nullable<int> fStatus { get; set; }
            public int fCreatorID { get; set; }
            public System.DateTime fCreateTime { get; set; }
            public Nullable<int> fUpdateID { get; set; }
            public System.DateTime fUpdateTime { get; set; }
        
            public virtual sysMenusView sysMenus { get; set; }
            public virtual ICollection<sysPermissListView> sysPermissList { get; set; }
        }
    }
    




    展开全文
  • T4 模板

    2019-03-26 09:24:00
    T4 模板语言是一个模板代码生成语言,什么意思呢?就是通过模板,生成我们相应的所需要的文件。很好理解,比如我们在写类的时候,我们通常是新建一个类文件,这个时候它出来的页面并非空白,而是有一些基本的内容,...

    T4 模板语言是一个模板代码生成语言,什么意思呢?就是通过模板,生成我们相应的所需要的文件。很好理解,比如我们在写类的时候,我们通常是新建一个类文件,这个时候它出来的页面并非空白,而是有一些基本的内容,比如我新建一个 MyTest的类文件:

    using  System;
    using  System.Collections.Generic;
    using  System.Linq;
    using  System.Text;
     
    namespace  BLL
    {
         class  MyTest
         {
         }
    }

      

    所以,上面的这些常用的信息就是用模板语言来进行新建的。

    T4 模板语言的后缀以.tt结尾的,我们可以在 VS 2008 或 VS 2010里面进行使用。如下图:

     

    看到了木有,第一个“预处理的文本模板”和第二个是文本模板。

    介绍2中模板的用途:

    One .预处理的文本模板

    先说说这个,这个是设计时的模板。可以在运行时在应用程序中生成文本字符串。 预处理过的模板有时称为“运行时文本模板”。什么是运行时模板呢?其实,也很好理解,比如我们在写C#代码的时候,我们也分为运行时的编译还是设计时,运行时就是在程序开始执行的时候才开始,而设计时是说你在写代码那一刻就开始编译。更具体的例子说,假如我们有一个错误,如果编译时错误,那么我们写完离开就会显示出来,可是有些错误在编译的时候,是无法知道的,比如说内存泄露等等,这个必须要等程序运行的时候才能知道。

    一般来说,预处理模板在项目中的使用比较大,因为它有一个partial的分部类,我们都知道,在VS里面为了便于对某些元素进行扩展,很多时候都使用的分部类。这里也不例外。而且我目前做的通过UML 类图生成代码 都是通过partial来进行扩展的。

    我们可以看到,它和文本模板(第二点会介绍)属性的唯一不同便是:自定义工具的值不同。预处理的是:TextTemplatingFilePreprocessor

    文本的是:TextTemplatingFileGenerator

    现在先建立预处理的文件,对于它的一些语法,我们暂时先不考虑,语法我们会在下一节进行说明。

    将创建一个扩展名为 .tt 的新文件。该文件的“自定义工具”属性设置为 TextTemplatingFilePreprocessor。如下图:

    具体操作过程如下:

    1.在解决方案资源管理器中,右击项目,指向“添加”,再单击“新建项”。

    2.在“添加新项”对话框中,选择“预处理文本模板”。(在 Visual Basic 中的“常用项\常规”下查看。)

    3.键入模板文件的名称。

    这里需要注意的一点是,模板文件名将在生成的代码中用作类名。因此,该名称不应包含空格或标点。

    4.单击“添加”。可以了,到这一步就OK了。

    然后会看到只有一行代码:<#@ template language="C#" #>

    现在我们,在这行代码的下面放入以下代码:

    <#@ output extension=".html" #>
    < h1 >列出所有数字:</ h2 >
    < table >
         <# for (int i = 1; i <= 10; i++)
            {
             #>
              < tr >< td >数字: <#= i #> </ td >
                  < td >倍数: <#= i * i #> </ td > </ tr >
         <# } #>
      </ table >

      

    我们现在只需要知道的是,它输出的类型是.html,extension=".html",即表明它输出的是网页文件。

    那我们怎么看它呢?

    比如我们需要在aspx里调用这个模板文件,那么我只需要在需要触发事件的方法下面调用这个就OK,比如我这里是在page_load的时候,把模板里的内容显示到页面上。

    protected  void  Page_Load( object  sender, EventArgs e)
             {
                 PreTextTemplate1 t4 = new  PreTextTemplate1();
                 string  str = t4.TransformText();
                 t4Div.InnerHtml = str;
             }

     

    页面,我放了一个div,如<div id="t4Div" runat="server"></div>,把runat设为server是为了在后台能调用,当然你也可以用其他空间进行渲染。

    你还可以在控制台进行显示,调用方法也和上面一样。比如在控制台输出的内容为:

    很酷吧。暂时先体验一下吧。

    好了,接下来我们来说说文本模板。

    Two.文本模板

    如上图所示,文本模板里的自定义工具是:TextTemplatingFileGenerator

    文本模板是一种在设计时显示的结果的一种模式.也就是所见所得的一种模式吧。

    1.生成html文件

    比如我现在还是上面的代码,新建一个文本模板,然后再下面写入一下代码:

    <#@ template debug="false" hostspecific="false" language="C#" #>

    <#@ output extension=".html" #>

    <html><body>

    <h1>Sales for Previous Month</h2>

    <table>

        <# for (int i = 1; i <= 10; i++)

           { #>

             <tr><td>Test name <#= i #> </td>

                 <td>Test value <#= i * i #> </td> </tr>

        <# } #>

     </table>

    This report is Company Confidential.

    </body></html>

    这个 结果怎么看呢?很简单,你只需要展开TextTemplate1.tt,你会看到一个TextTemplate1.html(因为你上面的output设置了.html)文件。

    2.生成文本文件

    <#@ output extension=".txt" #>

    列出数字从1 到 10:

    <#

           int list=10;

           for(int i=0;i<10;i++){

    #><#= i #><#= } #>

    它和上面的唯一的区别就是output的不一样。查看方式也很easy哦。

    3. 生成类文件

    你还可以生成类文件,它主要的都合上面的一样,唯一的区别就是output的输出类型是.cs文件。

    <#@ output extension=".cs" #>

    <# var properties = new string [] {"P1", "P2", "P3"}; #>

    class MyGeneratedClass {

    <#

      foreach (string propertyName in properties)

      { #>

      private int <#= propertyName #> = 0;

    <# } #>

    }

    生成

    class MyGeneratedClass {

      private int P1 = 0;

      private int P2 = 0;

      private int P3 = 0;

    }

     

    在T4里是没有像VS的C#调试那么简单,在左边设置一个调试点,然后点击运行就OK了。

    不过,也差不多吧!值需要的只是:<# Debugger.Break(); #> 把这个放到你需要调试的地方,等你运行的时候,就会自动的跳到这里啦。然后,你就可以看到你的内容,比如我在我的项目中调试中的结果:

    ,然后 安F10 行执行,F11是但不执行,都是一样的啦。

     

    转载:https://www.cnblogs.com/damonlan/archive/2012/01/12/2320429.html

    转载于:https://www.cnblogs.com/sylone/p/10598161.html

    展开全文
  • PeTaPOCO T4模板

    2018-09-06 14:04:40
    PetaPOCO的T4模板,可以帮助大家使用该T4模板快速的搭建框架。
  • 上一篇文章 ——T4模板之菜菜鸟篇,我们囫囵吞枣的创建了与“T4模板”有关的文件。在创建各个文件的这一个过程中,我们对于T4模板有了那么丁点的认识。现在就带着之前的那些问题,正式的迈入对“T4模板”的学习。 ...

    一、回顾

    上一篇文章 ——T4模板之菜菜鸟篇,我们囫囵吞枣的创建了与“T4模板”有关的文件。在创建各个文件的这一个过程中,我们对于T4模板有了那么丁点的认识。现在就带着之前的那些问题,正式的迈入对“T4模板”的学习。

    二、概念

    2.1、类型

    T4 文本模板有两种类型:

    • 设计时 T4 文本模板
    • 运行时 T4 文本模板

    三、简要教程

    我们只讲“设计时T4文本模板”,其他的都TMD属于高级部分了,哥不懂给不给?

    打开之前我们创建的“TextTemplate_.tt”文件:

    image

    很明显的有一个特征,那么就是他们都是这种模式:

    <#@ 指令 属性=“”#>

    就这样定了,我们按行来学习

    3.1、指令:

    3.1.1、模板指令

    <#@ template debug="false" hostspecific="false" language="C#"#> 

    说的是这个模板,不可以调试,不提供host这个属性,用的是C#语言。它的完整模式如下,中括号表示可选,没有写它将按照默认处理。

    <#@ template [language="VB"] [compilerOptions="options"] [culture="code"] [debug="true"] [hostspecific="true"] [inherits="templateBaseClass"] [visibility="internal"] [linePragmas="false"] #>
    3.1.2、程序集指令

    <#@ assembly name="System.Core"#>   它的作用类似于在 Visual Studio 项目中添加程序集引用。

    3.1.3、导入指令

    <#@ import namespace="System.Linq"#>   它等效于 C# 中的 “using System.Linq;”。

    3.1.4、输出指令

    <#@ output extension=".txt" #>   它就是告诉你,T4模板最终将生产.txt对应后缀的文件。

    3.2、控制块

    不难发现,如上截图,我们生成的“TextTemplate_.txt”它里面确实是什么内容都没有的。因此,更进一步的学习是“控制块”,对于不同控制块的组合,便能生成我们所需要的文件。

    image

    • <# 标准控制块 #> 可以包含语句。

    • <#= 表达式控制块 #> 可以包含表达式。

    • <#+ 类特征控制块 #> 可以包含方法、字段和属性,就像一个类的内部

    3.3、心动不如行动

    唱首歌吧!“我是一只小小小鸟……”:

    image

    我是zeje,我们来定义一个变量 string name =“zeje”,再看看效果:

    image

    哥已经压抑了很久了,一起来呐喊吧:

    image

    发泄够了吧?仔细想想,这个类<#+ 类特征控制块 #> 还没用上。好吧,zeje就在这里自我介绍下吧:

    image

    既然都自我介绍过了,是不是可以开溜了呢?还是给大家都个红包吧!(这里可能需要另外说明,先凑合着看吧!)

    image

    生成结果如下:

    image[63]

     本文转载于:http://www.cnblogs.com/zeje/p/5248340.html

     

    转载于:https://www.cnblogs.com/jonfan/p/7223326.html

    展开全文
  • T4模板.zip

    2019-08-02 10:26:04
    自动生成三层的T4模板代码,内部只要修改连接EF路径就可以在项目中正常使用
  • T4模板生成演示 关于如何使用T4模板生成样板代码的快速简单演示。 此演示从SQL Server数据库生成视图。 代码生成器使用T4(SQLViews.tt)模板作为输出代码。 该应用程序从SQL数据库收集表信息(表名,模式名等)...
  • wcf T4模板

    2014-03-24 15:31:49
    这几天没事学习的,还没入门,用T4模板批量生成wcf。主要是记录下 环境是vs2012.
  • T4 模板引擎 生成实体

    2016-09-02 10:55:18
    T4 模板引擎 生成实体
  • T4模板生成邮件

    2016-10-29 13:02:23
    使用C#代码控制T4模板,输出到任意位置。
  • VS2017 T4模板生产

    2017-12-28 13:26:29
    T4模板 代码生产 模型生成
  • T4模板生成model类

    2016-12-13 14:21:50
    T4模板生成多个文件的model类 适用于oracle数据库
  • T4模板快速生成代码: 以快速生Dal文件为例,下面为T4模板文件的内容 <#@ template debug="false" hostspecific="true" language="C#" #> <#@ include file="EF.Utility.CS.ttinclude"#> <#@ ...

    T4模板快速生成代码:

    以快速生Dal文件为例,下面为T4模板文件的内容

    <#@ template debug="false" hostspecific="true" language="C#" #>
    <#@ include file="EF.Utility.CS.ttinclude"#>
    <#@ output extension=".cs" #>
    <#
    CodeGenerationTools code = new CodeGenerationTools(this);
    MetadataLoader loader = new MetadataLoader(this);
    CodeRegion region = new CodeRegion(this, 1);
    MetadataTools ef = new MetadataTools(this);
    string inputFile = @"..\\MIS.Model\\MIS.edmx";
    EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
    string namespaceName = code.VsNamespaceSuggestion();
    EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
    #>
    using MIS.IDal;
    using MIS.Model;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MIS.Dal
    {
    <#foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
      {#>
        public partial class <#=entity.Name#>Dal : BaseDal<<#=entity.Name#>>, I<#=entity.Name#>Dal
        {
        }
    <#}#>
    }

    说明:
    <# C#代码 #>:#号中间的内容为C#代码,正常的C#怎么写这里就怎样写。

    <#= 输出值 #>:输出一个C#代码中能得到的值。

    在这些之外的都是原样输出,包括空格。

    使用时只需要把以上模板的inputFile改成自己的,其它原样输出的根据自己情况把现成的Dal文件照常复制出来就行了(没有的要以自己写一个出来用T4模板生成后删除就行了)

    生成后的代码如下:

     1 using MIS.IDal;
     2 using MIS.Model;
     3 using System;
     4 using System.Collections.Generic;
     5 using System.Linq;
     6 using System.Text;
     7 using System.Threading.Tasks;
     8 
     9 namespace MIS.Dal
    10 {
    11     public partial class sys_ActionDal : BaseDal<sys_Action>, Isys_ActionDal
    12     {
    13     }
    14     public partial class sys_ManagerDepartmentDal : BaseDal<sys_ManagerDepartment>, Isys_ManagerDepartmentDal
    15     {
    16     }
    17     public partial class sys_PermissionDal : BaseDal<sys_Permission>, Isys_PermissionDal
    18     {
    19     }
    20     public partial class sys_UserDal : BaseDal<sys_User>, Isys_UserDal
    21     {
    22     }
    23 }

     

    转载于:https://www.cnblogs.com/jonfan/p/7223283.html

    展开全文
  • T4模板实例工具

    2015-02-10 11:10:32
    强大的T4模板生成工具,针对WPF MVVM
  • C# T4模板

    2020-12-14 21:58:09
    1.1、T4简介1.2、T4模板类型1)运行时模板2)设计时模板1.3、插件安装二、T4 Hello World示例1)项目右键"添加"->"新建项"->"文本模板",将名称更改为Program.tt。2)Program.tt的代码如下:3)点击保存,即可...
  • t4模板动态生成接口

    2018-07-24 15:25:22
    使用t4模板动态生成已配置好的接口,方便其他项目中使用。
  • C# 生成T4模板所需文件

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,184
精华内容 2,873
关键字:

t4模板