2011-10-27 8 views
5

Sto cercando un tutorial, guida o software in grado di generare semplici POCO per alcune tabelle SQL Server da utilizzare in ASP.NET MVC. Qualcosa di simile a questo:Semplice generazione T4 per Simple POCO

1) Tenere un elenco dei nomi delle tabelle nel database di SQL Server che dovrebbe avere un POCO generato

2) Portare l'elenco per qualche programma

3) Il programma genera un semplice POCO (più simile a DTO) in un singolo file .cs, o si aggiunge a Poco.cs. Ad ogni modo, non importa.

Ad esempio:

public class MyDto 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public bool? IsMale {get; set;} 
} 

4) Eseguire il programma ogni volta che voglio ri-generare

Il programma della POCO potrebbe essere WinForm, a riga di comando, o qualcos'altro. Non importa.

risposta

8

ho voluto rispondere a questo, ma stato occupato.

Ho creato un semplice esempio su come leggere uno schema di database e generare classi e proprietà da questo.

Fondamentalmente si dovrebbe essere in grado di tagliare questo in un file TT (vedere Oleg Sychs blog su come iniziare), aggiornare la stringa di connessione e salvare per eseguire il modello.

Non pretendo che questo è un campione completo ma potrebbe servire come punto di partenza per voi:

<#@ template language = "C#"       #> 
    <#@ assembly name  = "Microsoft.CSharp"    #> 
    <#@ assembly name  = "System.Core"     #> 
    <#@ assembly name  = "System.Data"     #> 
    <#@ import  namespace = "System.Collections.Generic" #> 
    <#@ import  namespace = "System.Dynamic"    #> 
    <#@ import  namespace = "System.Linq"     #> 
    <#@ import  namespace = "System.Data.SqlClient"  #> 

    <# 
    var namespaceName = "Poco2"; 
    // Update the connection string to something appropriate 
    var connectionString = @"Data Source=localhost\SQLExpress;Initial Catalog=MyTest;Integrated Security=True"; 
    #> 

    <# 
    using (var db = new SqlConnection (connectionString)) 
    using (var cmd = db.CreateCommand()) 
    { 
     db.Open(); 
     var tables    = ReadRows (cmd, "SELECT * FROM sys.tables").ToArray(); 

     var columns    = ReadRows (cmd, "SELECT * FROM sys.columns").ToLookup (k => k.object_id); 

     var indexes    = ReadRows (cmd, "SELECT * FROM sys.indexes").ToLookup (k => k.object_id); 
     var indexColumns  = ReadRows (cmd, "SELECT * FROM sys.index_columns").ToLookup (k => k.object_id); 

     var foreignKeys   = ReadRows (cmd, "SELECT * FROM sys.foreign_keys").ToArray(); 
     var foreignKeyColumns = ReadRows (cmd, "SELECT * FROM sys.foreign_key_columns").ToArray(); 
    #> 
    namespace <#=namespaceName#> 
    { 
    using System; 
    using System.Data.Linq.Mapping; 

    <# 
     foreach (var table in tables) 
     {   
    #> 
    [Table] 
    partial class <#=table.name#> 
    { 
    <# 
      IEnumerable<dynamic> tc = columns[table.object_id]; 
      var tableColumns = tc.OrderBy (r => r.column_id).ToArray();   

      IEnumerable<dynamic> ti = indexes[table.object_id]; 
      var tableIndexes = ti.ToArray();   

      var primaryKeyIndex = tableIndexes.FirstOrDefault (i => i.is_primary_key); 
      var primaryKeyColumns = new Dictionary<dynamic, dynamic>(); 
      if (primaryKeyIndex != null) 
      { 
       IEnumerable<dynamic> pc = indexColumns[table.object_id]; 
       primaryKeyColumns = pc 
       .Where (c => c.index_id == primaryKeyIndex.index_id) 
       .ToDictionary (c => c.column_id, c => c.key_ordinal) 
       ; 
      } 

      foreach (var tableColumn in tableColumns) 
      { 
       var type = MapToType (tableColumn.user_type_id, tableColumn.max_length, tableColumn.is_nullable); 

    #> 
     [Column (IsPrimaryKey = <#=primaryKeyColumns.ContainsKey (tableColumn.column_id) ? "true" : "false"#>)] 
     public <#=type#> <#=tableColumn.name#> {get;set;} 

    <# 
      } 
    #> 

    } 
    <# 
     } 
    #> 
    } 
    <# 
    } 
    #> 

    <#+ 

    struct DataType 
    {  
     public readonly int  SizeOf; 
     public readonly string SingularType; 
     public readonly string PluralType; 

     public DataType (
      int sizeOf, 
      string singularType, 
      string pluralType = null 
      ) 
     { 
      SizeOf   = sizeOf; 
      SingularType = singularType; 
      PluralType  = pluralType ?? (singularType + "[]"); 
     } 

    } 
    static Dictionary<int, DataType> dataTypes = new Dictionary<int, DataType> 
     { 
      {61 , new DataType (8, "DateTime"   )}, 
      {127 , new DataType (8, "long"    )}, 
      {165 , new DataType (1, "byte"    )}, 
      {231 , new DataType (2, "char" , "string")}, 
     }; 

    static string MapToType (int typeId, int maxLength, bool isNullable) 
    { 
     DataType dataType; 

     if (dataTypes.TryGetValue (typeId, out dataType)) 
     { 
      var length = maxLength > 0 ? (maxLength/dataType.SizeOf) : int.MaxValue; 
      if (length > 1) 
      { 
       return dataType.PluralType; 
      } 
      else 
      { 
       return dataType.SingularType + (isNullable ? "?" : ""); 
      } 
     } 
     else 
     { 
      return "UnknownType_"+ typeId; 
     } 
    } 

    static IEnumerable<dynamic> ReadRows (SqlCommand command, string sql) 
    { 
     command.CommandText = sql ?? ""; 

     using (var reader = command.ExecuteReader()) 
     { 
      while (reader.Read()) 
      { 
       var dyn = new ExpandoObject(); 
       IDictionary<string, object> dic = dyn; 

       for (var iter = 0; iter < reader.FieldCount; ++iter) 
       { 
        dic[reader.GetName(iter) ?? ""] = reader.GetValue(iter); 
       } 

       yield return dyn; 
      } 

     } 
    } 


    #> 
+1

Ha funzionato per me dopo aver aggiunto i tipi di dati mancanti necessari. Grazie. – kampsj

2

Ho creato uno strumento di generazione personalizzato simile circa 1 anno fa e non ho trovato una risorsa completa e unificata per raggiungere questo obiettivo.

Oleg Sych fornisce una serie di post di blog sull'utilizzo di T4 allo his blog e gestisce una libreria per aiutare con la generazione T4, T4 Toolbox. Ho fatto molto affidamento su entrambi durante lo sviluppo.

Per il rilevamento dello schema del database nei modelli T4, ho utilizzato SQL Server Management Objects.

Eseguo i miei modelli T4 da Visual Studio.

0

È possibile utilizzare il modello classes.tt (in linqtemplates, più SQLServer.ttinclude) in subsonic 3 (eseguito in Visual Studio). http://subsonicproject.com/ Le proprietà generate hanno variabili di supporto e alcune linee aggiuntive per supportare INotifyPropertyChanging e INotifyPropertyChanged, ma è possibile modificare il modello per eliminare quelle linee.

Ecco un esempio di output e il modello:

public partial class Order 
{ 
    public int OrderID { get; set; } 
    public string CustomerID { get; set; } 
    public int? EmployeeID { get; set; } 
    public DateTime? OrderDate { get; set; } 
    public DateTime? RequiredDate { get; set; } 
    public DateTime? ShippedDate { get; set; } 
    public int? ShipVia { get; set; } 
    public decimal? Freight { get; set; } 
    public string ShipName { get; set; } 
    public string ShipAddress { get; set; } 
    public string ShipCity { get; set; } 
    public string ShipRegion { get; set; } 
    public string ShipPostalCode { get; set; } 
    public string ShipCountry { get; set; } 
} 


<#@ template language="C#" debug="False" hostspecific="True" #> 
<#@ output extension=".cs" #> 
<#@ include file="SQLServer.ttinclude" #> 
<# 
    var tables = LoadTables(); 
#> 
using System; 
using System.ComponentModel; 
using System.Linq; 

namespace <#=Namespace#> 
{ 


<# foreach(Table tbl in tables){#>  

    /// <summary> 
    /// A class which represents the <#=tbl.Name#> table in the <#=DatabaseName#> Database. 
    /// This class is queryable through <#=DatabaseName#>DB.<#=tbl.ClassName#> 
    /// </summary> 

    public partial class <#=tbl.ClassName#> 
    { 
     #region Properties 

<#  foreach(var col in tbl.Columns){ 
      if (tbl.ClassName == col.CleanName) 
      { 
       col.CleanName += "X"; 
      } 
#> 
     public <#=col.SysType#><#=CheckNullable(col)#> <#=col.CleanName#> { get; set; } 
<#  }#> 

     #endregion 

    } 

<#}#> 
} 
0

St4bby a github. Open source. T4. Abbastanza facile da leggere e manipolare come desideri.

Problemi correlati