c# - 通用关系到复合 C# 对象映射器

标签 c# datareader

我有以下代码能够将 Reader 映射到简单对象。问题是万一对象是复合的,它就无法映射。如果它本身是一个类,我无法通过检查属性来执行递归

prop.PropertyType.IsClass 因为调用 DataReaderMapper() 需要 Type。关于如何实现或其他方法的任何想法?另外,目前我不希望使用任何 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;

        }
    }
}

最佳答案

不要制作 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);
            }
        }
}

就像那样。这会使用默认构造的实例递归地初始化所有类类型属性,并为它们分配数据读取器值。

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

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

关于c# - 通用关系到复合 C# 对象映射器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30230595/

相关文章:

.net - 使用 IDataRecord 从数据库中读取 blob 字段

c# - 使用 C# 和存储过程从 SQL Server 检索 VarChar(MAX)

c# - 我应该将变量声明为尽可能接近它们将被使用的范围吗?

c# - 如何优化此算法中的内存使用?

mysql - 从 vb.net 数据读取器中的多个表读取

c# - 如何只从 SqlDataReader 中获取一些行?

python - 如何访问 Pandas 的 DataReader 中的日期行?

c# - 如何在方法期间通过依赖注入(inject)从池中获取 DbContext 实例?

c# - 列出.Add(x)。 x 是引用还是值?

c# - Delegate.BeginInvoke()/EndInvoke() 实现