【问题标题】:how to generate a Custom Class via t4?如何通过 t4 生成自定义类?
【发布时间】:2011-12-26 23:05:22
【问题描述】:

我正在尝试通过 T4 生成以下代码。

using System;
using MyDAL;

namspace Test
{
// Select...
   public partial class MyCustomer
   {
      public int id { get ;set;}
      public string name { get ;set;}
      public string surname { get ;set;}

      public MyCustomer()
      {

      }

      public List<Customer> GetById(int id)
      {
         // do something...
      }
   }
        // Delete,Update,Save
   public partial class MyCustomer
   {
       public bool Save(new MyCustomer)
       {
         // do something...
       }

       public bool delete(int id)
       {
         // do something...
       }

       public bool Update(int id)
       {
         // do something...
       }
   }
}

我目前拥有的 T4 模板:


<#@ template language="C#"#>
<#@ assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #>
<#@ assembly name="Microsoft.SqlServer.ConnectionInfo" #>
<#@ assembly name="Microsoft.SqlServer.Smo" #>



<#@ import namespace="Microsoft.SqlServer.Management.Smo" #>

namespace DbClasses
{
    <#

    Server srv = new Server();
    Database db = new Database(srv,"NarDb");
    db.Refresh();
    foreach (Table tablo in db.Tables)
        {

             WriteLine("public class " +tablo.Name+"{");
            foreach (Column column in tablo.Columns)
                {
                    if(column.DataType.Name=="nvarchar")
                             WriteLine("public "+"string " +""+column.Name+";");
                    else
                         WriteLine("public "+"int " +""+column.Name+";");
                }
                WriteLine("}");



        }
   #>
}

【问题讨论】:

  • 如果您想准确生成您发布的代码,则不需要 T4。但我猜你想从 something 生成你的类?还有你的 T4 怎么样?

标签: c# design-patterns code-generation t4


【解决方案1】:

我不确定您面临的问题是什么:但是您的 T4 代码没有任何问题。第二个类中 Save 方法的签名有新的,这是一个错误:

public bool Save(new MyCustomer)

应该是

public bool Save(MyCustomer customer)

此外,GetById 应该返回一个元素而不是列表。

我通过为表、列等编写虚拟类来尝试您编写的代码而不连接到数据库,您编写的 T4 代码没有任何问题,除了根据您的要求,您编写的代码没有'不生成部分类,而不是创建属性。它只是为每个具有公共字段(不是属性)的表创建一个非部分类。如果您想生成部分类和属性(和方法),那么您的方向是正确的(我添加了制表符和换行符以使其在生成的文件中看起来很漂亮,您只需在此处按 Ctrl+K、Ctrl+D 即可重新格式化不过:

<#

foreach (Table tablo in tables)
{
//start class
WriteLine("public partial class My" +tablo.Name+"\n{");
foreach (Column column in tablo.Columns)
{
if(column.DataType.Name=="nvarchar")
WriteLine("\tpublic string " + column.Name+"{get; set;}");
else
WriteLine("\tpublic int " + column.Name+"{get; set;}");
}
//output the contructor
WriteLine("\tpublic My" + tablo.Name + "()\n\t{\n\t\t//constructor\n\t}" );
WriteLine("\tpublic List<" + tablo.Name + "> GetById(int id)\n\t{\n\t\t// do something\n\t}");
//end class
WriteLine("}");

//output comment and start class
WriteLine("//Delete,Update,Save");
WriteLine("public partial class My" +tablo.Name+"\n{");
WriteLine("\tpublic bool Save(My" + tablo.Name + " " + tablo.Name + ")\n\t{\n\t\t// do something\n\t}");
WriteLine("\tpublic bool Delete(int id)\n\t{\n\t\t// do something\n\t}");
WriteLine("\tpublic bool Update(int id)\n\t{\n\t\t// do something\n\t}");
WriteLine("}");

}
#>

【讨论】:

    【解决方案2】:

    虽然不完整,但或许下面的 T4 可以作为一些灵感。

    这就是它的使用方法:

    using (var sqlConnection = new SqlConnection (@"Data Source=localhost\SQLExpress;Initial Catalog=MinTest;Integrated Security=True"))
    using (var sqlCommand = sqlConnection.CreateCommand ())
    {
        sqlConnection.Open ();
        var customers = sqlCommand.Get_Customer (Id:10, CompId:20).ToArray ();
    
        foreach (var customer in customers)
        {
            Console.WriteLine (customer.Id);
            Console.WriteLine (customer.CompId);
            Console.WriteLine (customer.FirstName);
            Console.WriteLine (customer.LastName);
            Console.WriteLine (customer.OrgNo);
        }
    
        var deleteCount = sqlCommand.Delete_Customer (Id:20, CompId:20);
        Console.WriteLine ("Deleted rows: {0}", deleteCount);
        Console.ReadKey ();
    }
    

    T4:

    <#@ template    language    = "C#"                                      #> 
    <#@ assembly    name        = "Microsoft.SqlServer.Management.Sdk.Sfc"  #> 
    <#@ assembly    name        = "Microsoft.SqlServer.ConnectionInfo"      #> 
    <#@ assembly    name        = "Microsoft.SqlServer.Smo"                 #> 
    <#@ assembly    name        = "System.Core"                             #> 
    <#@ assembly    name        = "System.XML"                              #> 
    <#@ import      namespace   = "Microsoft.SqlServer.Management.Smo"      #> 
    <#@ import      namespace   = "System.Collections.Generic"              #> 
    <#@ import      namespace   = "System.Linq"                             #> 
    <#@ import      namespace   = "System.Text"                             #> 
    
    // ReSharper disable InconsistentNaming
    // ReSharper disable PartialTypeWithSinglePart
    
    <#
        // Update SQL Server and namespace
        var nameSpace   = "MyNameSpace";
        var server      = new Server (@"localhost\SQLExpress");
        var database    = new Database (server,"MyDB");
        var maxTables   = int.MaxValue; 
        database.Refresh (); 
    #>
    
    namespace <#=nameSpace#>
    { 
        using System;
        using System.Collections.Generic;
        using System.Data.SqlClient;
    
        static partial class Extensions
        {
            static int Lookup (Dictionary<string, int> dic, string key)
            {
                int value;
                return dic.TryGetValue (key, out value) ? value : -1;
            }
    
            static byte[] GetByteArray (this SqlDataReader reader, int index)
            {
                var byteLength = reader.GetBytes (index, 0, null, 0, 0);
                var bytes = new byte[byteLength];
                reader.GetBytes (index, 0, bytes, 0, bytes.Length);
                return bytes;
            }
    
    <#
        foreach (var table in database.Tables.OfType<Table> ().Take (maxTables))
        {
    #>
            // --------------------------------------------------------------------
            // Deletes <#=table.Name#>
            // --------------------------------------------------------------------
            public static int Delete_<#=table.Name#> (
                this SqlCommand command
    <#
                    foreach (var column in table.Columns.OfType<Column> ().Where (c => c.InPrimaryKey))
                    {
    #>
                ,   <#=GetType (column)#> <#=column.Name#>
    <#
                    }
    #>
                )
            {
                if (command != null)
                {
                    command.CommandText = "DELETE FROM <#=table.Schema#>.<#=table.Name#> <#=GetWhereClause (table)#>";
                    command.Parameters.Clear ();
    <#
                    foreach (var column in table.Columns.OfType<Column> ().Where (c => c.InPrimaryKey))
                    {
    #>
                    command.Parameters.AddWithValue (@"<#=column.Name#>", <#=column.Name#>);
    <#
                    }
    #>
                    return command.ExecuteNonQuery ();
                }
                else
                {
                    return 0;
                }
            }
            // --------------------------------------------------------------------
    
            // --------------------------------------------------------------------
            // Gets <#=table.Name#>
            // --------------------------------------------------------------------
            public static IEnumerable<<#=table.Name#>> Get_<#=table.Name#> (
                this SqlCommand command
    <#
                    foreach (var column in table.Columns.OfType<Column> ().Where (c => c.InPrimaryKey))
                    {
    #>
                ,   <#=GetType (column)#> <#=column.Name#>
    <#
                    }
    #>
                )
            {
                if (command != null)
                {
                    command.CommandText = "SELECT * FROM <#=table.Schema#>.<#=table.Name#> <#=GetWhereClause (table)#>";
                    command.Parameters.Clear ();
    <#
                    foreach (var column in table.Columns.OfType<Column> ().Where (c => c.InPrimaryKey))
                    {
    #>
                    command.Parameters.AddWithValue (@"<#=column.Name#>", <#=column.Name#>);
    <#
                    }
    #>
                    using (var reader = command.ExecuteReader ())
                    {
                        foreach (var row in reader.To_<#=table.Name#> ())
                        {
                            yield return row;
                        }
                    }
                }
            }
            // --------------------------------------------------------------------
    
            // --------------------------------------------------------------------
            // Deserializes a <#=table.Name#>
            // --------------------------------------------------------------------
            public static IEnumerable<<#=table.Name#>> To_<#=table.Name#> (this SqlDataReader reader)
            {
                if (reader != null)
                {
                    var fieldCount = reader.FieldCount;
                    var dictionary = new Dictionary<string, int> ();
                    for (var iter = 0; iter < fieldCount; ++iter)
                    {
                        dictionary[reader.GetName (iter)] = iter;
                    }
    
                    while (reader.Read ())
                    {
                        var instance = new <#=table.Name#> ();
    <#
                    foreach (var column in table.Columns.OfType<Column> ())
                    {
    #>
                        {
                            var index = Lookup (dictionary, "<#=column.Name#>");
                            if (index > -1)
                            {
                                instance.<#=column.Name #> = reader.<#=GetGetter (column)#> (index);
                            }
                        }
    <#                
                    }
    #>
                        yield return instance;
                    }
                }
            }
            // --------------------------------------------------------------------
    
    <#
        }
    #>
        }
    
    <#
        foreach (var table in database.Tables.OfType<Table> ().Take (maxTables))
        {
    #>
        // ------------------------------------------------------------------------
        // Table: <#=table.Name#>
        // ------------------------------------------------------------------------
        partial class <#=table.Name#>
        {
    <#
            foreach (var column in table.Columns.OfType<Column> ())
            {
    #>
            // <#=column.DataType.Name#> (<#=column.Nullable#>, <#=column.DataType.MaximumLength#>, <#=column.DataType.SqlDataType#>)
            public <#=GetType (column)#> <#=column.Name#> {get;set;}
    <#
            }
    #>
        }
        // ------------------------------------------------------------------------
    
    <#
        }
    #>
    
    } 
    
    <#+
        sealed class DataTypeDescriptor
        {
            public readonly bool IsValueType;
            public readonly string Type;
            public readonly string Getter;
    
            public DataTypeDescriptor (
                bool isValueType, 
                string type,
                string getter = null
                )
            {
                IsValueType     = isValueType;
                Type            = type;
                Getter          = getter ?? ("Get" + type);
            }
        }
    
        readonly static Dictionary<SqlDataType, DataTypeDescriptor> s_typeDescriptors =
            new Dictionary<SqlDataType, DataTypeDescriptor> ()
                {
                    // Unsupported:
                    // ------------
                    // None, 
                    // UserDefinedDataType, 
                    // UserDefinedDataType, 
                    // XML, 
                    // SysName, 
                    // UserDefinedTableType, 
                    // HierarchyId, 
                    // Geometry, 
                    // Geography
                    {SqlDataType.BigInt             , new DataTypeDescriptor (true  , "Int64"            )},
                    {SqlDataType.Binary             , new DataTypeDescriptor (true  , "Byte"            )},
                    {SqlDataType.Bit                , new DataTypeDescriptor (true  , "Boolean"            )},
                    {SqlDataType.Char               , new DataTypeDescriptor (false , "String"          )},
                    {SqlDataType.DateTime           , new DataTypeDescriptor (true  , "DateTime"        )},
                    {SqlDataType.Decimal            , new DataTypeDescriptor (true  , "Decimal"         )},
                    {SqlDataType.Float              , new DataTypeDescriptor (true  , "Double"          )},
                    {SqlDataType.Image              , new DataTypeDescriptor (false , "byte[]"  , "GetByteArray"          )},
                    {SqlDataType.Int                , new DataTypeDescriptor (true  , "Int32"             )},
                    {SqlDataType.Money              , new DataTypeDescriptor (true  , "Decimal"         )},
                    {SqlDataType.NChar              , new DataTypeDescriptor (false , "String"          )},
                    {SqlDataType.NText              , new DataTypeDescriptor (false , "String"          )},
                    {SqlDataType.NVarChar           , new DataTypeDescriptor (false , "String"          )},
                    {SqlDataType.NVarCharMax        , new DataTypeDescriptor (false , "String"          )},
                    {SqlDataType.Real               , new DataTypeDescriptor (true  , "Double"          )},
                    {SqlDataType.SmallDateTime      , new DataTypeDescriptor (true  , "DateTime"        )},
                    {SqlDataType.SmallInt           , new DataTypeDescriptor (true  , "Int16"           )},
                    {SqlDataType.SmallMoney         , new DataTypeDescriptor (true  , "Decimal"         )},
                    {SqlDataType.Text               , new DataTypeDescriptor (false , "String"          )},
                    {SqlDataType.Timestamp          , new DataTypeDescriptor (false , "byte[]"  , "GetByteArray"          )},
                    {SqlDataType.TinyInt            , new DataTypeDescriptor (true  , "Byte"            )},
                    {SqlDataType.UniqueIdentifier   , new DataTypeDescriptor (false , "byte[]"  , "GetByteArray"          )},
                    {SqlDataType.VarBinary          , new DataTypeDescriptor (false , "byte[]"  , "GetByteArray"        )},
                    {SqlDataType.VarBinaryMax       , new DataTypeDescriptor (false , "byte[]"  , "GetByteArray"        )},
                    {SqlDataType.VarChar            , new DataTypeDescriptor (false , "String"          )},
                    {SqlDataType.VarCharMax         , new DataTypeDescriptor (false , "String"          )},
                    {SqlDataType.Variant            , new DataTypeDescriptor (false , "object"  , "GetValue")},
                    {SqlDataType.Numeric            , new DataTypeDescriptor (true  , "Decimal"         )},
                    {SqlDataType.Date               , new DataTypeDescriptor (true  , "DateTime"        )},
                    {SqlDataType.Time               , new DataTypeDescriptor (true  , "TimeSpan"        )},
                    {SqlDataType.DateTimeOffset     , new DataTypeDescriptor (true  , "DateTimeOffset"  )},
                    {SqlDataType.DateTime2          , new DataTypeDescriptor (true  , "DateTime"        )},
                };                                                                                  
    
    
        static string GetGetter (Column column)
        {
            var dataType = column.DataType;
            DataTypeDescriptor descriptor;
            if (!s_typeDescriptors.TryGetValue (dataType.SqlDataType, out descriptor))
            {
                return
                        "Error__Unsupported_Type_" 
                    +   dataType.SqlDataType
                    ;
            }
    
            return descriptor.Getter;
        }
    
        static string GetType (Column column)
        {
            var dataType = column.DataType;
            DataTypeDescriptor descriptor;
            if (!s_typeDescriptors.TryGetValue (dataType.SqlDataType, out descriptor))
            {
                return 
                        "Error__Unsupported_Type_" 
                    +   dataType.SqlDataType
                    ;
            }
    
            if (column.Nullable && descriptor.IsValueType)
            {
                return descriptor.Type + "?";
            }
    
            return descriptor.Type;
        }
    
        static string GetWhereClause (Table table)
        {
            var sb = new StringBuilder ("WHERE ");
    
            var first = true;
            foreach (var column in table.Columns.OfType<Column> ().Where (c => c.InPrimaryKey))
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    sb.Append (" AND ");
                }
    
                sb.AppendFormat ("{0} = @{0}", column.Name);
            }
    
            return sb.ToString ();
        }
    #>
    

    【讨论】:

      猜你喜欢
      • 2012-01-26
      • 2011-02-27
      • 1970-01-01
      • 2013-01-25
      • 2023-03-21
      • 1970-01-01
      • 2020-01-07
      • 1970-01-01
      • 2020-05-07
      相关资源
      最近更新 更多