使用反射和valueinjector映射复合对象

本文关键字:映射 复合 对象 valueinjector 反射 | 更新日期: 2023-09-27 18:12:37

也许这个问题,总是在这个论坛上问,但我没有找到我需要的那个。我的问题是我有一个像这样的复合类

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

并使用反射将其映射到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,但当我应用到这个例子时,我也遇到了同样的问题。

现在我使用valueinjector,从我读到它可以解决我的问题。但我有钱。Id值与customer . company .Id和customer .Id相同。Name = " and customer . 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);
}

有什么问题吗?

使用反射和valueinjector映射复合对象

为什么要使用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);
关于你的问题……如果有从数据库拉空的可能性…