2011-10-27 5 views
1

多分この質問では、このフォーラムで尋ねられますが、私が必要とするものは見つかりません。ReflectionとValueInjecterを使用した複合オブジェクトのマッピング

public static Object FillDataRecord(IDataRecord dr, Object obj) 
{ 
    try 
    { 
     Type type = obj.GetType(); 
     PropertyInfo[] properties = type.GetProperties(); 

     for (int i = 0; i < dr.FieldCount; i++) 
     { 
      if (!dr[i].ToString().Equals(string.Empty)) 
      { 
       type.GetProperty(dr.GetName(i)).SetValue(obj, dr[i], null); 
      } 
     } 

     return obj; 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 
} 
: 私の問題は、私は、顧客データ

string sql = "SELECT cust.id, cust.name, comp.name AS [CompanyName] FROM Customer cust INNER JOIN Company comp ON cust.Company = comp.Id"; 
.... 
using (IDataReader dr = db.ExecuteReader(cmd)) 
{ 
    if (dr.Read()) 
    { 
     customer = (Customer)FillDataRecord(dr, customer); 
    } 
} 

と反射、コードを使用して、Customerクラス(オブジェクト)にマッピングを取得すると、私はこの

class Customer 
{ 
    private int Id { set; get; } 
    private int Name { set; get; } 
    private Company Company { set; get; } 
    ... 
} 

class Company 
{ 
    private int Id { set; get; } 
    private string Name { set; get; } 
    ... 
} 

のような複合クラスを持っています

CompanyNameをマッピングすると、「オブジェクト参照がオブジェクトのインスタンスに設定されていません」というエラーが返されます。私はデバッグして問題を知っていますが、今までは解決できません。

私はAutoMapperまたはDapperについて知っていますが、私がこのケースに当てはまるとき、同じ問題もあります。

今私はValueInjecterを使用しています。私が読んだところでは、私の問題を解決することができます。 cust.Company.Idとcust.Name = "" とcust.Company.Name = ""

string sql = "select cust.id, cust.name, comp.name from customer cust inner join company comp on cust.company = comp.id"; 

while (dr.Read()) 
{ 
    var cust = new Customer(); 
    cust.InjectFrom<ReaderInjection>(dr); 

    cust.Company = new Company(); 
    cust.Company.InjectFrom<ReaderInjection>(dr); 

    list.add(cust); 
} 

と同じ しかし、私が持っているcust.Id値が間違っているものはありますか?私を助けてください。

答えて

2

なぜあなたはオブジェクトを使用していますか?なぜそれを一般的にしないのですか?

public static T FillDataRecord<T>(IDataRecord dr) where T : new() 
{ 
    T returnedInstance = new T(); 
    string fieldName = default(string); 

    try 
    { 
     PropertyInfo[] properties = typeof(T).GetProperties(); 

     fieldName = dr.GetName(i); 

     foreach (PropertyInfo property in properties) 
     { 
      if (property.Name == fieldName) 
      { 
       // Handle the DBNull conversion issue.. 
       if (dr.GetValue(i) == DBNull.Value) 
        property.SetValue(returnedInstance, null, null); 
       else 
        property.SetValue(returnedInstance, dr[i], null); 
      } 
     } 

     return returnedInstance; 
    } 
    catch (Exception ex) 
    { 
     // Handle exception here 
    } 
} 

次にあなたがこれを行うことができます::そうのような

Customer _customer = FillDataRecord<Customer>(dr); 

それとも、この:あなたの質問への答えで

CustomerDetails _customerDetails = FillDataRecord<CustomerDetails>(dr); 

.. theresの場合からNULLを引く可能性をあなたはそれをチェックしなければなりません。

+0

私はジェネリックについてほとんど知っていません。改善していただきありがとうございますが、変数iがあなたのコードで宣言されておらず、fieldname型の文字列なのでエラーが発生しましたか? – Willy

+0

私はお詫び申し上げます。はい、fieldNameは文字列です。 – chemicalNova

+0

気にしませんが、record.GetName(i)、record.GetValue(i)とrecord [i]には何がありますか?あなたはまだそれを定義していません – Willy

関連する問題