I have implemented the code to convert datareader to list of objects. My intention was to not to use column name string literals while reading the datareader.
public static IEnumerable<T> GetListFromDataReader<T>(IDataReader reader) where T : new()
{
var properties = typeof(T).GetProperties();
var modelProperties = new List<string>();
var columnList = (reader.GetSchemaTable().Select()).Select(r => r.ItemArray[0].ToString());
while (reader.Read())
{
var element = Activator.CreateInstance<T>();
Dictionary<string, string> dbMappings = DBColumn(element);
string columnName;
foreach (var f in properties)
{
if (!columnList.Contains(f.Name) && !dbMappings.ContainsKey(f.Name))
continue;
columnName = dbMappings.ContainsKey(f.Name) ? dbMappings[f.Name] : f.Name;
var o = (object)reader[columnName];
if (o.GetType() != typeof(DBNull)) f.SetValue(element, ChangeType(o, f.PropertyType), null);
}
yield return element;
}
}
public static object ChangeType(object value, Type conversion)
{
var t = conversion;
if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
if (value == null)
{
return null;
}
t = Nullable.GetUnderlyingType(t); ;
}
return Convert.ChangeType(value, t);
}
public static Dictionary<string,string> DBColumn<T>(T item) where T:new()
{
Dictionary<string, string> dbMappings = new Dictionary<string, string>();
var type = item.GetType();
var properties = type.GetProperties();
foreach (var property in properties)
{
var attributes = property.GetCustomAttributes(false);
var columnMapping = attributes
.FirstOrDefault(a => a.GetType() == typeof(DbColumnAttribute));
if (columnMapping != null)
{
dbMappings.Add(property.Name, ((DbColumnAttribute)columnMapping).Name);
}
}
return dbMappings;
}
Can somebody help me by providing a review? I am doubtful of too much usage of reflections in loops would downgrade the performance. Or should I compromise and better to go with string literals itself while reading?