Сопоставление составного объекта с использованием Reflection и ValueInjecter - PullRequest
1 голос
/ 27 октября 2011

Может быть, этот вопрос всегда задают на этом форуме, но я не могу найти тот, который мне нужен.Моя проблема в том, что у меня есть составной класс, подобный этому

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

Когда я получаю данные клиента

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

и сопоставляю их с классом клиента (Object), используя отражение, код:

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

При отображении CompanyName он выдаст ошибку «Ссылка на объект не установлена ​​на экземпляр объекта».Я отладил и знаю проблему, но до сих пор не могу ее решить.

Я знаю об AutoMapper или Dapper, но когда я обращаюсь к этому случаю, у меня возникает та же проблема.

Теперь я использую ValueInjecter, из того, что я прочитал, можно решить мою проблему.Но у меня есть значение cust.Id одинаковое с 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);
}

Что-то не так?Пожалуйста, помогите мне.

1 Ответ

2 голосов
/ 27 октября 2011

Почему вы используете Object? Почему бы не сделать его общим? Вот так:

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);

В ответ на ваш вопрос ... если есть возможность извлечь NULL из базы данных ... вы должны проверить это.

...