how to generate a Custom Class via t4?

我的未来我决定 提交于 2019-12-05 04:41:29

问题


I am trying to generate the below code via 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...
       }
   }
}

The T4 template I have so far:


<#@ 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("}");



        }
   #>
}

回答1:


I'm not exactly sure what is the problem you are facing: but there is nothing wrong with your T4 code. The signature of the Save method in the second class has new and that's an error:

public bool Save(new MyCustomer)

should be

public bool Save(MyCustomer customer)

Also, GetById should return one element not a list.

I tried out the code you wrote without connecting to a database by writing dummy classes for Table, Column, etc and there is nothing wrong with the T4 code you wrote, except that, as per your requirements, the code your wrote doesn't generate partial classes, not does it create properties. It just creates a single non-partial class for each table with public fields (not properties). If you want to generate partial classes and properties (and methods) you're in the right direction (I added tabs and newlines to make it look pretty in the generated file, you can just press Ctrl+K, Ctrl+D there to reformat it though:

<#

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:


It's not complete but perhaps the following T4 can serve as some inspiration.

This is how it can be used:

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 ();
    }
#>


来源:https://stackoverflow.com/questions/8093395/how-to-generate-a-custom-class-via-t4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!