2011-10-27 6 views
1

이 질문은 항상이 포럼에서 묻지 만 필요한 항목을 찾지 못했습니다.리플렉션과 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); 
    } 
} 

을 얻을 반사를 사용하여 고객 클래스 (객체)에 매핑 할 때 나는이

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

왜 개체를 사용하고 있습니까? 왜 그것을 일반화하지 않습니까? 그래서 같이이,

Customer _customer = FillDataRecord<Customer>(dr); 

을 또는 :

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 
    } 
} 

그럼 당신은이 작업을 수행 할 수 있습니다 ..

대답에
CustomerDetails _customerDetails = FillDataRecord<CustomerDetails>(dr); 

질문에 경우 프로그래머로부터 NULL을 당겨 가능성 데이터베이스 .. 당신은 그것을 확인해야합니다.

+0

저는 Generic에 대해 거의 알지 못합니다. 개선 주셔서 감사합니다,하지만 난 변수에 난 당신의 코드에서 선언하지 않았기 때문에 오류가있어 fieldname 유형 문자열입니까? – Willy

+0

죄송합니다. 예, fieldName은 문자열입니다. – chemicalNova

+0

신경 쓰지 마라. 그러나 나는 record.GetName (i), record.GetValue (i)와 record [i]에 대해 무엇을 할까? 당신은 아직 그것을 정의하지 않았습니다 – Willy