与复合C#对象映射器的通用关系

Abd*_*han 13 c# datareader

我有以下能够映射Reader到简单对象的代码.麻烦在于对象是复合的,它无法映射.如果它是一个类本身,我无法通过检查属性来执行递归

prop.PropertyType.IsClass as Type需要调用DataReaderMapper().有关如何实现这一点或其他方法的任何想法?此外,目前我不想使用任何ORM.

public static class MapperHelper
{

    /// <summary>
    /// extension Method for Reader :Maps reader to type defined
    /// </summary>
    /// <typeparam name="T">Generic type:Model Class Type</typeparam>
    /// <param name="dataReader">this :current Reader</param>
    /// <returns>List of Objects</returns>
    public static IEnumerable<T> DataReaderMapper<T>(this IDataReader dataReader)where T : class, new()
    {
        T obj = default(T);

        //optimized taken out of both foreach and while loop
        PropertyInfo[] PropertyInfo;
        var temp = typeof(T);
        PropertyInfo = temp.GetProperties();

        while (dataReader.Read())
        {  
            obj = new T();

            foreach (PropertyInfo prop in PropertyInfo)
            {
                if (DataConverterHelper.ColumnExists(dataReader,prop.Name) && !dataReader.IsDBNull(prop.Name))
                {
                    prop.SetValue(obj, dataReader[prop.Name], null);
                }
            }
            yield return obj;

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

usr*_*usr 9

不要DataReaderMapper递归.只需使映射部分递归:

static void Assign(IDataReader reader, object instance) {
        foreach (PropertyInfo prop in PropertyInfo)
        {
            if (IsValue(prop))
            {
                prop.SetValue(obj, dataReader[prop.Name], null);
            }
            else if (IsClass(prop)) {
               var subInstance = Activator.CreateInstance(prop.PropertyType);
                prop.SetValue(obj, subInstance, null);
               Assign(subInstance, dataReader);
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

像那样.这将使用默认构造实例递归初始化所有类类型属性,并为其分配数据读取器值.

代码明显简化.我省略了你的一些东西和IsValue/ IsClass或留下来实现你喜欢的.此外,您可能希望使用命名方案,以便a.b.c作为列名映射到该属性.这可以通过将当前名称前缀作为参数传递给Assign.

进一步说明,DataReaderMapper不需要通用.我这样说是因为你挣扎着.替换typeof(T)Type参数并返回IEnumerable<object>.然后调用Cast<T>()方法的结果.所以你看到这个算法原则上可以在没有泛型的情况下工作.