• 使用T4模板生成POCO类


    为什么叫T4?因为简写为4个T。

    T4(Text Template Transformation Toolkit)是微软官方在VisualStudio 2008中开始使用的代码生成引擎。在 Visual Studio 中,“T4 文本模板”是由一些文本块和控制逻辑组成的混合模板,它可以生成文本文件。 在 Visual C# 或 Visual Basic 中,控制逻辑编写为程序代码的片段。生成的文件可以是任何类型的文本,例如网页、资源文件或任何语言的程序源代码。现在的VS中只要与代码生成相关的场景基本上都能找T4的身影,比如MVC的视图模板,Entity Framwork的DataContext模板等等。

    若论灵活性,各种代码生成工具还真不如T4模板。

    在VS2013种默认没有了T4模板,取而代之的是文本模板,但是他们的后缀名都是.tt。我们可以通过NuGet安装T4模板。

    安装之后,我们在项目中新建项的时候,在VS模板中就多了两项和T4模板相关的模板。

    当我们在新建的T4模板中进行代码编写的时候,默认是没有智能提示的,我们需要再安装一个T4Editor的VS插件tangibleT4EditorPlusModellingToolsVS2013.msi。

    下载地址:

    https://marketplace.visualstudio.com/items?itemName=tangibleengineeringGmbH.tangibleT4Editor230plusmodelingtoolsforVS2013

     由于我这里用的是VS2013,所以按照13的插件,安装插件时先关闭VS,安装完成之后在T4模板中编写代码时就有了智能提示了。

    关于T4模板的详细讲解,大家可以参照一下博客文章:

    你必须懂的 T4 模板:体系架构

    (译)理解 T4 模板:<#@ parameter #> 指令

    我这里要说的是,如何在项目中替代其它的代码工具来使用,比如说,自动生成数据库中的POCO类。

     思路:1、我们要查询中数据库中的表和字段。2、根据数据表名才,将其生成多个POCO类文件

    How to do?

    开发环境:VS2013

    准备工作:添加必须的程序集引用

    在自己电脑上面用everythin找到Microsoft.VisualStudio.TextTemplating.Interfaces.10.0.dll,然后添加引用,如果没有,你就网上下载一个。

    方式一

     1、添加一个T4模板文件DbHelper,将其后缀修改为.ttinclude,因为我是将其作为内嵌的T4文件,不修改扩展名的话,会将其当成T4模板文件进行生成。

    <#+
        public class DbHelper
        {
            #region GetDbTables
            
            public static List<DbTable> GetDbTables(string connectionString, string database, string tables = null)
            {
                
                if (!string.IsNullOrEmpty(tables))
                {
                    tables = string.Format(" and obj.name in ('{0}')", tables.Replace(",", "','"));
                }
                #region SQL
                string sql = string.Format(@"SELECT
                                        obj.name tablename,
                                        schem.name schemname,
                                        idx.rows,
                                        CAST
                                        (
                                            CASE 
                                                WHEN (SELECT COUNT(1) FROM sys.indexes WHERE object_id= obj.OBJECT_ID AND is_primary_key=1) >=1 THEN 1
                                                ELSE 0
                                            END 
                                        AS BIT) HasPrimaryKey                                         
                                        from {0}.sys.objects obj 
                                        inner join {0}.dbo.sysindexes idx on obj.object_id=idx.id and idx.indid<=1
                                        INNER JOIN {0}.sys.schemas schem ON obj.schema_id=schem.schema_id
                                        where type='U' {1}
                                        order by obj.name", database, tables);
                #endregion
                DataTable dt = GetDataTable(connectionString, sql);
                return dt.Rows.Cast<DataRow>().Select(row => new DbTable
                {
                    TableName = row.Field<string>("tablename"),
                    SchemaName = row.Field<string>("schemname"),
                    Rows = row.Field<int>("rows"),
                    HasPrimaryKey = row.Field<bool>("HasPrimaryKey")
                }).ToList();
            }
            #endregion
    
            #region GetDbColumns
            
            public static List<DbColumn> GetDbColumns(string connectionString, string database, string tableName, string schema = "dbo")
            {
                #region SQL
                string sql = string.Format(@"
                                        WITH indexCTE AS
                                        (
                                            SELECT 
                                            ic.column_id,
                                            ic.index_column_id,
                                            ic.object_id    
                                            FROM {0}.sys.indexes idx
                                            INNER JOIN {0}.sys.index_columns ic ON idx.index_id = ic.index_id AND idx.object_id = ic.object_id
                                            WHERE  idx.object_id =OBJECT_ID(@tableName) AND idx.is_primary_key=1
                                        )
                                        select
                                        colm.column_id ColumnID,
                                        CAST(CASE WHEN indexCTE.column_id IS NULL THEN 0 ELSE 1 END AS BIT) IsPrimaryKey,
                                        colm.name ColumnName,
                                        systype.name ColumnType,
                                        colm.is_identity IsIdentity,
                                        colm.is_nullable IsNullable,
                                        cast(colm.max_length as int) ByteLength,
                                        (
                                            case 
                                                when systype.name='nvarchar' and colm.max_length>0 then colm.max_length/2 
                                                when systype.name='nchar' and colm.max_length>0 then colm.max_length/2
                                                when systype.name='ntext' and colm.max_length>0 then colm.max_length/2 
                                                else colm.max_length
                                            end
                                        ) CharLength,
                                        cast(colm.precision as int) Precision,
                                        cast(colm.scale as int) Scale,
                                        prop.value Remark
                                        from {0}.sys.columns colm
                                        inner join {0}.sys.types systype on colm.system_type_id=systype.system_type_id and colm.user_type_id=systype.user_type_id
                                        left join {0}.sys.extended_properties prop on colm.object_id=prop.major_id and colm.column_id=prop.minor_id
                                        LEFT JOIN indexCTE ON colm.column_id=indexCTE.column_id AND colm.object_id=indexCTE.object_id                                        
                                        where colm.object_id=OBJECT_ID(@tableName)
                                        order by colm.column_id", database);
                #endregion
                SqlParameter param = new SqlParameter("@tableName", SqlDbType.NVarChar, 100) { Value = string.Format("{0}.{1}.{2}", database, schema, tableName) };
                DataTable dt = GetDataTable(connectionString, sql, param);
                return dt.Rows.Cast<DataRow>().Select(row => new DbColumn()
                {
                    ColumnID = row.Field<int>("ColumnID"),
                    IsPrimaryKey = row.Field<bool>("IsPrimaryKey"),
                    ColumnName = row.Field<string>("ColumnName"),
                    ColumnType = row.Field<string>("ColumnType"),
                    IsIdentity = row.Field<bool>("IsIdentity"),
                    IsNullable = row.Field<bool>("IsNullable"),
                    ByteLength = row.Field<int>("ByteLength"),
                    CharLength = row.Field<int>("CharLength"),
                    Scale = row.Field<int>("Scale"),
                    Remark = row["Remark"].ToString()
                }).ToList();
            }
    
            #endregion     
    
    
            #region GetDataTable
            
            public static DataTable GetDataTable(string connectionString, string commandText, params SqlParameter[] parms)
            {
                using (SqlConnection connection = new SqlConnection(connectionString))
                {
                    SqlCommand command = connection.CreateCommand();
                    command.CommandText = commandText;
                    command.Parameters.AddRange(parms);
                    SqlDataAdapter adapter = new SqlDataAdapter(command);
    
                    DataTable dt = new DataTable();
                    adapter.Fill(dt);
    
                    return dt;
                }
            }
    
            #endregion
        }
    
        #region DbTable
        /// <summary>
        /// 表结构
        /// </summary>
        public sealed class DbTable
        {
            /// <summary>
            /// 表名称
            /// </summary>
            public string TableName { get; set; }
            /// <summary>
            /// 表的架构
            /// </summary>
            public string SchemaName { get; set; }
            /// <summary>
            /// 表的记录数
            /// </summary>
            public int Rows { get; set; }
    
            /// <summary>
            /// 是否含有主键
            /// </summary>
            public bool HasPrimaryKey { get; set; }
        }
        #endregion
    
        #region DbColumn
        /// <summary>
        /// 表字段结构
        /// </summary>
        public sealed class DbColumn
        {
            /// <summary>
            /// 字段ID
            /// </summary>
            public int ColumnID { get; set; }
    
            /// <summary>
            /// 是否主键
            /// </summary>
            public bool IsPrimaryKey { get; set; }
    
            /// <summary>
            /// 字段名称
            /// </summary>
            public string ColumnName { get; set; }
    
            /// <summary>
            /// 字段类型
            /// </summary>
            public string ColumnType { get; set; }
    
            /// <summary>
            /// 数据库类型对应的C#类型
            /// </summary>
            public string CSharpType
            {
                get
                {
                    return SqlServerDbTypeMap.MapCsharpType(ColumnType);
                }
            }
    
            /// <summary>
            /// 
            /// </summary>
            public Type CommonType
            {
                get
                {
                    return SqlServerDbTypeMap.MapCommonType(ColumnType);
                }
            }
    
            /// <summary>
            /// 字节长度
            /// </summary>
            public int ByteLength { get; set; }
    
            /// <summary>
            /// 字符长度
            /// </summary>
            public int CharLength { get; set; }
    
            /// <summary>
            /// 小数位
            /// </summary>
            public int Scale { get; set; }
    
            /// <summary>
            /// 是否自增列
            /// </summary>
            public bool IsIdentity { get; set; }
    
            /// <summary>
            /// 是否允许空
            /// </summary>
            public bool IsNullable { get; set; }
    
            /// <summary>
            /// 描述
            /// </summary>
            public string Remark { get; set; }
        }
        #endregion
    
        #region SqlServerDbTypeMap
    
        public class SqlServerDbTypeMap
        {
            public static string MapCsharpType(string dbtype)
            {
                if (string.IsNullOrEmpty(dbtype)) return dbtype;
                dbtype = dbtype.ToLower();
                string csharpType = "object";
                switch (dbtype)
                {
                    case "bigint": csharpType = "long"; break;
                    case "binary": csharpType = "byte[]"; break;
                    case "bit": csharpType = "bool"; break;
                    case "char": csharpType = "string"; break;
                    case "date": csharpType = "DateTime"; break;
                    case "datetime": csharpType = "DateTime"; break;
                    case "datetime2": csharpType = "DateTime"; break;
                    case "datetimeoffset": csharpType = "DateTimeOffset"; break;
                    case "decimal": csharpType = "decimal"; break;
                    case "float": csharpType = "double"; break;
                    case "image": csharpType = "byte[]"; break;
                    case "int": csharpType = "int"; break;
                    case "money": csharpType = "decimal"; break;
                    case "nchar": csharpType = "string"; break;
                    case "ntext": csharpType = "string"; break;
                    case "numeric": csharpType = "decimal"; break;
                    case "nvarchar": csharpType = "string"; break;
                    case "real": csharpType = "Single"; break;
                    case "smalldatetime": csharpType = "DateTime"; break;
                    case "smallint": csharpType = "short"; break;
                    case "smallmoney": csharpType = "decimal"; break;
                    case "sql_variant": csharpType = "object"; break;
                    case "sysname": csharpType = "object"; break;
                    case "text": csharpType = "string"; break;
                    case "time": csharpType = "TimeSpan"; break;
                    case "timestamp": csharpType = "byte[]"; break;
                    case "tinyint": csharpType = "byte"; break;
                    case "uniqueidentifier": csharpType = "Guid"; break;
                    case "varbinary": csharpType = "byte[]"; break;
                    case "varchar": csharpType = "string"; break;
                    case "xml": csharpType = "string"; break;
                    default: csharpType = "object"; break;
                }
                return csharpType;
            }
               
            public static Type MapCommonType(string dbtype)
            {
                if (string.IsNullOrEmpty(dbtype)) return Type.Missing.GetType();
                dbtype = dbtype.ToLower();
                Type commonType = typeof(object);
                switch (dbtype)
                {
                    case "bigint": commonType = typeof(long); break;
                    case "binary": commonType = typeof(byte[]); break;
                    case "bit": commonType = typeof(bool); break;
                    case "char": commonType = typeof(string); break;
                    case "date": commonType = typeof(DateTime); break;
                    case "datetime": commonType = typeof(DateTime); break;
                    case "datetime2": commonType = typeof(DateTime); break;
                    case "datetimeoffset": commonType = typeof(DateTimeOffset); break;
                    case "decimal": commonType = typeof(decimal); break;
                    case "float": commonType = typeof(double); break;
                    case "image": commonType = typeof(byte[]); break;
                    case "int": commonType = typeof(int); break;
                    case "money": commonType = typeof(decimal); break;
                    case "nchar": commonType = typeof(string); break;
                    case "ntext": commonType = typeof(string); break;
                    case "numeric": commonType = typeof(decimal); break;
                    case "nvarchar": commonType = typeof(string); break;
                    case "real": commonType = typeof(Single); break;
                    case "smalldatetime": commonType = typeof(DateTime); break;
                    case "smallint": commonType = typeof(short); break;
                    case "smallmoney": commonType = typeof(decimal); break;
                    case "sql_variant": commonType = typeof(object); break;
                    case "sysname": commonType = typeof(object); break;
                    case "text": commonType = typeof(string); break;
                    case "time": commonType = typeof(TimeSpan); break;
                    case "timestamp": commonType = typeof(byte[]); break;
                    case "tinyint": commonType = typeof(byte); break;
                    case "uniqueidentifier": commonType = typeof(Guid); break;
                    case "varbinary": commonType = typeof(byte[]); break;
                    case "varchar": commonType = typeof(string); break;
                    case "xml": commonType = typeof(string); break;
                    default: commonType = typeof(object); break;
                }
                return commonType;
            }
        }
        #endregion
        
    
    #>
    View Code

    上面的代码就是查询数据库中的表和字段。

    2、同样添加另一个T4模板文件,并修改后缀名Manager.ttinclude

    <#@ assembly name="System.Data.Linq"
    #><#@ assembly name="EnvDTE"
    #><#@ assembly name="System.Xml"
    #><#@ assembly name="System.Xml.Linq"
    #><#@ import namespace="System.Collections.Generic"
    #><#@ import namespace="System.IO"
    #><#@ import namespace="System.Text"
    #><#@ import namespace="Microsoft.VisualStudio.TextTemplating"
    #><#+
    // https://raw.github.com/damieng/DamienGKit
    // http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited
    
    // Manager class records the various blocks so it can split them up
    class Manager {
        private class Block {
            public String Name;
            public int Start, Length;
            public bool IncludeInDefault;
        }
    
        private Block currentBlock;
        private readonly List<Block> files = new List<Block>();
        private readonly Block footer = new Block();
        private readonly Block header = new Block();
        private readonly ITextTemplatingEngineHost host;
        private readonly StringBuilder template;
        protected readonly List<String> generatedFileNames = new List<String>();
    
        public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) {
            return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template);
        }
    
        public void StartNewFile(String name) {
            if (name == null)
                throw new ArgumentNullException("name");
            CurrentBlock = new Block { Name = name };
        }
    
        public void StartFooter(bool includeInDefault = true) {
            CurrentBlock = footer;
            footer.IncludeInDefault = includeInDefault;
        }
    
        public void StartHeader(bool includeInDefault = true) {
            CurrentBlock = header;
            header.IncludeInDefault = includeInDefault;
        }
    
        public void EndBlock() {
            if (CurrentBlock == null)
                return;
            CurrentBlock.Length = template.Length - CurrentBlock.Start;
            if (CurrentBlock != header && CurrentBlock != footer)
                files.Add(CurrentBlock);
            currentBlock = null;
        }
    
        public virtual void Process(bool split, bool sync = true) {
            if (split) {
                EndBlock();
                String headerText = template.ToString(header.Start, header.Length);
                String footerText = template.ToString(footer.Start, footer.Length);
                String outputPath = Path.GetDirectoryName("host.TemplateFile");
                files.Reverse();
                if (!footer.IncludeInDefault)
                    template.Remove(footer.Start, footer.Length);
                foreach(Block block in files) {
                    String fileName = Path.Combine(outputPath, block.Name);
                    String content = headerText + template.ToString(block.Start, block.Length) + footerText;
                    generatedFileNames.Add(fileName);
                    CreateFile(fileName, content);
                    template.Remove(block.Start, block.Length);
                }
                if (!header.IncludeInDefault)
                    template.Remove(header.Start, header.Length);
            }
        }
    
        protected virtual void CreateFile(String fileName, String content) {
            if (IsFileContentDifferent(fileName, content))
                File.WriteAllText(fileName, content);
        }
    
        public virtual String GetCustomToolNamespace(String fileName) {
            return null;
        }
    
        public virtual String DefaultProjectNamespace {
            get { return null; }
        }
    
        protected bool IsFileContentDifferent(String fileName, String newContent) {
            return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent);
        }
    
        private Manager(ITextTemplatingEngineHost host, StringBuilder template) {
            this.host = host;
            this.template = template;
        }
    
        private Block CurrentBlock {
            get { return currentBlock; }
            set {
                if (CurrentBlock != null)
                    EndBlock();
                if (value != null)
                    value.Start = template.Length;
                currentBlock = value;
            }
        }
    
        private class VSManager: Manager {
            private readonly EnvDTE.ProjectItem templateProjectItem;
            private readonly EnvDTE.DTE dte;
            private readonly Action<String> checkOutAction;
            private readonly Action<List<String>> projectSyncAction;
    
            public override String DefaultProjectNamespace {
                get {
                    return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString();
                }
            }
    
            public override String GetCustomToolNamespace(string fileName) {
                return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
            }
    
            public override void Process(bool split, bool sync) {
                if (templateProjectItem.ProjectItems == null)
                    return;
                base.Process(split, sync);
                if (sync)
                    projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null));
            }
    
            protected override void CreateFile(String fileName, String content) {
                if (IsFileContentDifferent(fileName, content)) {
                    CheckoutFileIfRequired(fileName);
                    File.WriteAllText(fileName, content);
                }
            }
    
            internal VSManager(ITextTemplatingEngineHost host, StringBuilder template)
                : base(host, template) {
                var hostServiceProvider = (IServiceProvider)host;
                if (hostServiceProvider == null)
                    throw new ArgumentNullException("Could not obtain IServiceProvider");
                dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE));
                if (dte == null)
                    throw new ArgumentNullException("Could not obtain DTE from host");
                templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
                checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName);
                projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames);
            }
    
            private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, List<String> keepFileNames) {
                var keepFileNameSet = new HashSet<String>(keepFileNames);
                var projectFiles = new Dictionary<String, EnvDTE.ProjectItem>();
                var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[0]) + ".";
                foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems)
                    projectFiles.Add(projectItem.FileNames[0], projectItem);
    
                // Remove unused items from the project
                foreach (var pair in projectFiles)
                    if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix))
                        pair.Value.Delete();
    
                // Add missing files to the project
                foreach(String fileName in keepFileNameSet)
                    if (!projectFiles.ContainsKey(fileName))
                        templateProjectItem.ProjectItems.AddFromFile(fileName);
            }
    
            private void CheckoutFileIfRequired(String fileName) {
                var sc = dte.SourceControl;
                if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
                    checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
            }
        }
    } #>
    View Code

    上面的代码是用来生成多文件的。

    3、新建T4模板文件PocoManager.tt,然后引入上面两个ttinclude文件。

    <#@ template debug="false" hostspecific="true" language="C#" #>
    <#@ assembly name="System.Data" #>
    <#@ assembly name="System.Data.DataSetExtensions.dll" #>
    <#@ assembly name="System.xml" #>
    <#@ import namespace="System" #>
    <#@ import namespace="System.Xml" #>
    <#@ import namespace="System.Collections.Generic" #>
    <#@ import namespace="System.Data" #>
    <#@ import namespace="System.Data.SqlClient" #>
    <#@ import namespace="System.IO" #>
    <#@ assembly name="System.Core" #>
    <#@ import namespace="System.Linq" #>
    <#@include file="$(ProjectDir)ModelsDbHelper.ttinclude"#> 
    <#@include file="$(ProjectDir)ModelsManager.ttinclude"#> 
    <# var manager = Manager.Create(Host, GenerationEnvironment); #>
    <# manager.StartHeader(); #>
    using System;
    using System.Collections.Generic;
    namespace My.Model
    {   
    <# manager.EndBlock(); #>
    <#        
        foreach (DbTable db in DbHelper.GetDbTables(config.ConnectionString, config.DbDatabase))
        {    
            string tb_name=db.TableName;
            manager.StartNewFile(tb_name+".cs");#>
        /// <summary>
        /// 实体-<#=tb_name#> 
        /// </summary>
       public partial class <#=tb_name#>
        {
            <# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tb_name)){#>
    /// <summary>
            /// <#=column.Remark#>
            /// </summary>        
            public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; }<#}#>   
        }
    <#//manager.EndBlock();    
        }            
        //conn.Close();  
    #>
    
    <# manager.StartFooter(); #>
    }
    <# manager.EndBlock(); #>
    
    <# manager.Process(true); #>
    <#+
        public class config
        {
            public static readonly string ConnectionString="Data Source=(local);Integrated Security=true;Initial Catalog=CarSYS;";
            public static readonly string DbDatabase="CarSYS";
        }
    #>
    View Code

    按Ctrl+S生成的代码如下:

     
     
    using System;
    using System.Collections.Generic;
    namespace My.Model
    {   
        /// <summary>
        /// 实体-Brand 
        /// </summary>
       public partial class Brand
        {
            /// <summary>
            /// 编号
            /// </summary>        
            public int BrandId { get; set; }
            /// <summary>
            /// 
            /// </summary>        
            public string BrandName { get; set; }
               
        }
        /// <summary>
        /// 实体-Car 
        /// </summary>
       public partial class Car
        {
            /// <summary>
            /// 编号
            /// </summary>        
            public int CarId { get; set; }
            /// <summary>
            /// 车名称
            /// </summary>        
            public string CarName { get; set; }
            /// <summary>
            /// 品牌编号
            /// </summary>        
            public int? BrandId { get; set; }
            /// <summary>
            /// 实体图的文件名
            /// </summary>        
            public string Picture { get; set; }
            /// <summary>
            /// 官方价
            /// </summary>        
            public decimal OfficialPrice { get; set; }
            /// <summary>
            /// 点击率
            /// </summary>        
            public int? Click { get; set; }
               
        }
        /// <summary>
        /// 实体-Product 
        /// </summary>
       public partial class Product
        {
            /// <summary>
            /// 
            /// </summary>        
            public Guid Id { get; set; }
            /// <summary>
            /// 
            /// </summary>        
            public string NAME { get; set; }
            /// <summary>
            /// 
            /// </summary>        
            public decimal Price { get; set; }
               
        }
    
    }
    View Code

    方式二

    操作方式一种的步骤2,然后新建T4模板Manager.tt,引入Manager.ttinclude

    <#@ template debug="false" hostspecific="true" language="C#" #>
    <#@ assembly name="System.Data" #>
    <#@ assembly name="System.xml" #>
    <#@ import namespace="System.Collections.Generic" #>
    <#@ import namespace="System.Data.SqlClient" #>
    <#@ import namespace="System.Data" #>
    <#@ assembly name="System.Core" #>
    <#@ import namespace="System.Linq" #>
    <#@include file="$(ProjectDir)ModelsManager.ttinclude"#> 
    <# var manager = Manager.Create(Host, GenerationEnvironment); #>
    <# manager.StartHeader(); #>
    using System;
    using System.Collections.Generic;
    namespace My.Model
    {   
    <# manager.EndBlock(); #>
    
    <#        
        string connectionString= "server=localhost;database=CarSYS;uid=sa;pwd=1127;";        
        SqlConnection conn = new SqlConnection(connectionString);
        conn.Open();
        
        string selectQuery ="SET FMTONLY ON; select * from @tableName; SET FMTONLY OFF;";
        SqlCommand command = new SqlCommand(selectQuery,conn);
        SqlDataAdapter ad = new SqlDataAdapter(command);
        System.Data.DataSet ds = new DataSet(); 
        System.Data.DataTable schema = conn.GetSchema("Tables");
    
        foreach(System.Data.DataRow row in schema.Rows)
        {    
            ds.Tables.Clear();
            string tb_name =row["TABLE_NAME"].ToString().Replace(" ","_"); 
            string tb_type=row["TABLE_TYPE"].ToString();
            if(tb_type!="BASE TABLE")
            {      
                continue;
            } 
            command.CommandText = selectQuery.Replace("@tableName","["+row["TABLE_NAME"].ToString()+"]");
            ad.FillSchema(ds,SchemaType.Mapped,tb_name);  
            manager.StartNewFile(tb_name+".cs");
    #>
        /// <summary>
        /// 实体-<#=tb_name#> 
        /// </summary>
        public partial class <#=tb_name#>    
        {    
            <#
            //PushIndent("        ");
            foreach (DataColumn dc in ds.Tables[0].Columns) 
            {
                string dataTypeName=dc.DataType.Name=="Byte[]"?"DateTime":dc.DataType.Name;
            #>
            /// <summary>
            /// <#=dc#>
            /// </summary> 
           <#     
            WriteLine("public " + dataTypeName + (dc.AllowDBNull && dataTypeName.ToLower() != "string" ? "? ": " ") + dc.ColumnName + " { get; set; }");
            }
            PopIndent();
            #>
        } 
    <#
            manager.EndBlock();    
        }            
        conn.Close();  
    #>
    
    <# manager.StartFooter(); #>
    }
    <# manager.EndBlock(); #>
    
    <# manager.Process(true); #>
    View Code

    按Ctrl+S生成的代码如下:

     
    using System;
    using System.Collections.Generic;
    namespace My.Model
    {   
    
        /// <summary>
        /// 实体-Brand 
        /// </summary>
        public partial class Brand    
        {    
                    /// <summary>
            /// BrandId
            /// </summary> 
           public Int32 BrandId { get; set; }
            /// <summary>
            /// BrandName
            /// </summary> 
           public String BrandName { get; set; }
        } 
        /// <summary>
        /// 实体-Car 
        /// </summary>
        public partial class Car    
        {    
                    /// <summary>
            /// CarId
            /// </summary> 
           public Int32 CarId { get; set; }
            /// <summary>
            /// CarName
            /// </summary> 
           public String CarName { get; set; }
            /// <summary>
            /// BrandId
            /// </summary> 
           public Int32? BrandId { get; set; }
            /// <summary>
            /// Picture
            /// </summary> 
           public String Picture { get; set; }
            /// <summary>
            /// OfficialPrice
            /// </summary> 
           public Decimal OfficialPrice { get; set; }
            /// <summary>
            /// Click
            /// </summary> 
           public Int32? Click { get; set; }
        } 
        /// <summary>
        /// 实体-Product 
        /// </summary>
        public partial class Product    
        {    
                    /// <summary>
            /// Id
            /// </summary> 
           public Guid Id { get; set; }
            /// <summary>
            /// NAME
            /// </summary> 
           public String NAME { get; set; }
            /// <summary>
            /// Price
            /// </summary> 
           public Decimal Price { get; set; }
        } 
    
    }
    View Code

    数据库CarSYS的脚本下载地址:

    USE [master]
    GO
    
    /****** Object:  Database [CarSYS]    Script Date: 2/17/2017 5:33:04 PM ******/
    CREATE DATABASE [CarSYS]
     CONTAINMENT = NONE
     ON  PRIMARY 
    ( NAME = N'CarSYS', FILENAME = N'F:DatabaseFileCarSYS.mdf' , SIZE = 212992KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
     LOG ON 
    ( NAME = N'CarSYS_log', FILENAME = N'F:DatabaseFileCarSYS_log.ldf' , SIZE = 321088KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
    GO
    
    ALTER DATABASE [CarSYS] SET COMPATIBILITY_LEVEL = 110
    GO
    
    IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
    begin
    EXEC [CarSYS].[dbo].[sp_fulltext_database] @action = 'enable'
    end
    GO
    
    ALTER DATABASE [CarSYS] SET ANSI_NULL_DEFAULT OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET ANSI_NULLS OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET ANSI_PADDING OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET ANSI_WARNINGS OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET ARITHABORT OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET AUTO_CLOSE OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET AUTO_CREATE_STATISTICS ON 
    GO
    
    ALTER DATABASE [CarSYS] SET AUTO_SHRINK OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET AUTO_UPDATE_STATISTICS ON 
    GO
    
    ALTER DATABASE [CarSYS] SET CURSOR_CLOSE_ON_COMMIT OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET CURSOR_DEFAULT  GLOBAL 
    GO
    
    ALTER DATABASE [CarSYS] SET CONCAT_NULL_YIELDS_NULL OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET NUMERIC_ROUNDABORT OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET QUOTED_IDENTIFIER OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET RECURSIVE_TRIGGERS OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET  DISABLE_BROKER 
    GO
    
    ALTER DATABASE [CarSYS] SET AUTO_UPDATE_STATISTICS_ASYNC OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET DATE_CORRELATION_OPTIMIZATION OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET TRUSTWORTHY OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET ALLOW_SNAPSHOT_ISOLATION OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET PARAMETERIZATION SIMPLE 
    GO
    
    ALTER DATABASE [CarSYS] SET READ_COMMITTED_SNAPSHOT OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET HONOR_BROKER_PRIORITY OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET RECOVERY FULL 
    GO
    
    ALTER DATABASE [CarSYS] SET  MULTI_USER 
    GO
    
    ALTER DATABASE [CarSYS] SET PAGE_VERIFY CHECKSUM  
    GO
    
    ALTER DATABASE [CarSYS] SET DB_CHAINING OFF 
    GO
    
    ALTER DATABASE [CarSYS] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF ) 
    GO
    
    ALTER DATABASE [CarSYS] SET TARGET_RECOVERY_TIME = 0 SECONDS 
    GO
    
    ALTER DATABASE [CarSYS] SET  READ_WRITE 
    GO
    View Code

    扩展:我们还可以在搭建项目框架的时候,通过反射等技术来自己编写T4模板。

    当然,我们还可以通过Entity Framework Power Tools这个开发神器来生成我们的EF Code代码。

  • 相关阅读:
    基于深度学习的单目图像深度估计
    OpenCV探索之路(二十三):特征检测和特征匹配方法汇总
    TensorFlow练习24: GANs-生成对抗网络 (生成明星脸)
    深度估计&平面检测小结
    论文翻译——Rapid 2D-to-3D conversion——快速2D到3D转换
    Opencv改变图像亮度和对比度以及优化
    如何将OpenCV中的Mat类绑定为OpenGL中的纹理
    Eclipse控制台中文乱码
    给java中的System.getProperty添加新的key value对
    中文简体windows CMD显示中文乱码解决方案
  • 原文地址:https://www.cnblogs.com/jiekzou/p/6410719.html
Copyright © 2020-2023  润新知