简体   繁体   English

通用SqlDataReader到Object Mapper

[英]Generic SqlDataReader to Object Mapper

I'm trying to build a generic mapper which will convert the results of a SqlDataReader into a class object. 我正在尝试构建一个通用映射器,它将SqlDataReader的结果转换为类对象。

Here is the basic structure for my code: 这是我的代码的基本结构:

public interface IObjectCore
    {
        //contains properties for each of my objects
    }

    public class ObjectMapper<T> where T : IObjectCore, new()
    {
        public List<T> MapReaderToObjectList(SqlDataReader reader)
        {
            var resultList = new List<T>();
            while (reader.Read())
            {
                var item = new T();
                Type t = item.GetType();
                foreach (PropertyInfo property in t.GetProperties())
                {
                    Type type = property.PropertyType;
                    string readerValue = string.Empty;

                    if (reader[property.Name] != DBNull.Value)
                    {
                        readerValue = reader[property.Name].ToString();
                    }

                    if (!string.IsNullOrEmpty(readerValue))
                    {
                        property.SetValue(property, readerValue.To(type), null);
                    }

                }
            }
            return resultList;
        }
    }

    public static class TypeCaster
    {
        public static object To(this string value, Type t)
        {
            return Convert.ChangeType(value, t);
        }
    }

For the most part it seems to work, but as soon as it tries to set the value of the property, I get the following error: 它在大多数情况下似乎工作,但一旦它试图设置属性的值,我得到以下错误:

Object does not match target type 对象与目标类型不匹配

on the line where I have property.SetValue . 在我有property.SetValue的行。

I have tried everything and I don't see what I might be doing wrong. 我已经尝试了一切,但我没有看到我可能做错了什么。

You are trying to set the value of the property you are looping through, I think your intent is to set the value of the newly created item that you have because that is going to match the Type that you are passing it based on item.GetType() 您正在尝试设置要循环的属性的值,我认为您的目的是设置新创建的项目的值,因为它将基于item.GetType与您传递的类型相匹配()

var item = new T();
//other code
property.SetValue(item , readerValue.To(type), null);

instead of 代替

property.SetValue(property, readerValue.To(type), null);

Also per comment , make sure you have: 同样根据评论 ,请确保您拥有:

resultList.Add(item);

Looks like this part is wrong: 看起来这部分是错的:

property.SetValue(property, readerValue.To(type), null);

Are you certain you want to apply SetValue by passing property to it? 您确定要通过将property传递给它来应用SetValue吗? Looks to me you should pass the object of type T which is item . 在我看来你应该传递T类型的对象,它是item

This then becomes: 然后变成:

property.SetValue(item, readerValue.To(type), null);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM