简体   繁体   中英

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.

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 .

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

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? Looks to me you should pass the object of type T which is item .

This then becomes:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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