2011-10-27 12 views
5

私は、ASP.NET MVCで使用するために、いくつかのSQL Serverテーブルに対して簡単なPOCOを生成できるチュートリアル、ガイダンス、またはソフトウェアを探しています。このような何か:シンプルなPOCOのシンプルなT4生成

1)POCOを持っている必要があり、SQL Serverデータベース内のテーブル名のリストを保持し、いくつかのプログラム

3)プログラムが生成するフィード一覧) を生成しました単一の.csファイルに単純なPOCO(DTOに似ています)を追加するか、Poco.cs.pcsに追加します。いずれにせよ、それは問題ではない。例えば

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

4)私はWinフォーム、コマンドライン、または何か他のものかもしれないPOCOの

プログラムを再生成したい時はいつでもプログラムを実行します。それは問題ではありません。

答えて

8

は、ここでのサンプル出力とテンプレートです。

私は、データベーススキーマを読み込み、これからクラスとプロパティを生成する簡単な例を作成しました。

基本的には、これをTTファイルにカットプレースすることができます(開始方法についてはOleg Sychs blogを参照)。接続文字列を更新して保存してテンプレートを実行します。

私は、これは完全なサンプルであることを主張しませんが、それはあなたのための出発点としての役割を果たすことができます:githubので

<#@ 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

私が必要とする欠落しているデータ型を追加した後で働いてくれました。ありがとう。 – kampsj

2

私は約1年前に同様のカスタム生成ツールを構築しましたが、この目標を達成するための統一された包括的なリソースは見つかりませんでした。

Oleg Sychは、T4を使用することに関するブログの投稿をhis blogで、T4の生成に役立つライブラリT4 Toolboxを提供しています。私は開発中に両方に大きく依存していました。

T4テンプレートのデータベーススキーマ検出では、SQL Server Management Objectsを使用しました。

Visual Studio内からT4テンプレートを実行します。

0

subsonic 3(visual studioで実行)のclasses.ttテンプレート(linqtemplatesとSQLServer.ttinclude)を使用できます。 http://subsonicproject.com/ 生成されたプロパティには、バッキング変数と、INotifyPropertyChangingおよびINotifyPropertyChangedをサポートするための余分な行がありますが、テンプレートを編集してこれらの行を取り出すことができます。私はこれに答えるために望んでいたが、忙しくしている

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。オープンソース。 T4。あなたが望むように、読んだり操作したりするのは簡単です。

関連する問題