2016-03-29 8 views
3

私は同じことを何度も何度もやり直しており、データテーブルから特定のクラスに行を変換するためのより一般的な方法を作りたがっています。C#で未知/汎用型のリストを作成するには?

私はジェネリックタイプの使用に経験がないので、私が望むものを探す方法を知るのは難しいですが、私は説明しようとします。

私はこのクラスを作成しました:

public class Class1 
{ 
    public Guid? Id{ get; set; } 
    public string Text1{ get; set; } 
    public string Text2{ get; set; } 
    public int TheNumber{ get; set; } 
} 

それから私は、クラス1を表し、データベースからデータをフェッチします。私はDataTableの形で結果を返します。データローの列の名前は、私のクラスのものとまったく同じです。だから私は何とか私の一般的なメソッドでClass1のインスタンスを作成することができます。私は多くを持っている

public static Class1 AssembleClass1(DataTable dtInfo) 
    { 
     Class1 obj = null; 

     if (dtInfo != null) 
     { 
      DataRow dr = dtInfo.Rows[0]; 
      obj = new StrategicObjectives(); 
      obj.Id= (Guid)dr["Id"]; 
      obj.Text1 = dr["Id"].ToString(); 
      obj.Text2 = dr["Id"].ToString(); 
      obj.TheNumber = (int)dr["TheNumber"]; 
     } 

     return obj; 
    } 

を今、私は何をしたいのdataTableとのClass1の型を取るジェネリックメソッドを作成することです(以降:この時点で

は、私はこのようなインスタンスを作成します私のプロジェクトの他のクラスも同じことができるようにしたい)。 その後、クラス1のタイプのリストを作成し、クラス1のパラメータを繰り返し、データテーブルの行に対応するのDataColumn(複数可)を検索し、クラス1の正しいパラメータに正しいデータロー値を割り当てるべきです。 私はそれも正しくデータrow列型を変換するClass1の各パラメーターの種類を確認する必要がありますね。

私はこれまで自分自身をこれを得たが、それが正しいかどうかはわからないと私は継続する方法がわからない..:

public static List<T> AssembleItem<T>(DataTable dtItems) 
    { 
     List<T> items = null; 

     if (dtItems != null) 
     { 
      items = new List<T>(); 

      foreach (DataRow dr in dtItems.Rows) 
      { 
       object item = (T)Activator.CreateInstance(typeof(T)); 
      } 
     } 

     return items; 
    } 

私は、誰かがこれで私を助けることを願って、私に聞いてくださいより多くの情報が必要な場合。

+0

まずあなたがdynamicキーワード、emitingコードとCasleProjectについて学ぶ必要があります。) –

+1

'obj.Text1 = DR [ "ID"]のToString();'あなたは[ "テキスト1"] 'DRをもしかしてToStringメソッド() ''( 'dr [" Text2 "]'それに応じて)? – HimBromBeere

+1

なぜDapperのような単純なORMマッパー使用しない - https://github.com/StackExchange/dapper-dot-net – Captain0

答えて

1

リフレクションを使用してクラスのプロパティ名を取得し、それらのプロパティ名を取り込むことができます。

public static List<T> AssembleItem<T>(DataTable dtItems) where T : new() 
{ 
    List<T> items = null; 
    if (dtItems != null) 
    { 
     items = new List<T>(); 
     foreach (DataRow dr in dtItems.Rows) 
     { 
      T item = new T(); 
      foreach (DataRow dr in dtItems.Rows) 
      { 
       T item = new T(); 

       Type t = typeof (T); 
       foreach (var property in t.GetProperties(BindingFlags.Public)) 
       { 
        var propertyname = property.Name; 

        //var data = ...get data from row in database with same column name as propertyname 

        property.SetValue(item,data); 
       } 
       // populate item from dr 
       items.Add(item); 
      } 
     } 
     return items; 
    } 
} 
+0

ありがとう、これはまさに正しい方向に私を得た! –

2

一部の質問に答えるには、型を導入するためにリフレクションを使用する必要はありません。型制約を使用して、次のようにパラメータのないコンストラクタを必要とすることができます。

public static List<T> AssembleItem<T>(DataTable dtItems) where T : new() 
{ 
    List<T> items = null; 
    if (dtItems != null) 
    { 
     items = new List<T>(); 
     foreach (DataRow dr in dtItems.Rows) 
     { 
      T item = new T(); 
      // populate item from dr 
      items.Add(item); 
     } 
    } 
    return items; 
} 
関連する問題