在与数据库的交互中,查询数据是经常要做的事情,每一组数据,我们都要去手写modle.属性 = dr["字段名"],这样去赋值,虽然各表的字段名,字段属性都不相同,但是回归本质,其实是同一个操作,于是,我便想到了用反射的方法,基于Model层,获取Model的全部属性,进行赋值,便可适用大部分的查询数据操作!
public static TEntity MapEntity<TEntity>(SqlDataReader reader) where TEntity : class, new()
{
try
{
var properties = typeof(TEntity).GetProperties();
var entity = new TEntity();
foreach (var propertie in properties)
{
if (propertie.CanWrite)//判断属性是否可写
{
try
{
var index = reader.GetOrdinal(propertie.Name.Replace("_", ""));//列序号
var data = reader.GetValue(index);//指定列值
if (data != DBNull.Value)
{
if (propertie.PropertyType.IsGenericType && propertie.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
propertie.SetValue(entity, Convert.ChangeType(data, propertie.PropertyType.GetGenericArguments()[0]), null);
}
else
{
propertie.SetValue(entity, Convert.ChangeType(data, propertie.PropertyType), null);
}
}
}
catch (IndexOutOfRangeException ex)
{
continue;
}
}
}
return entity;
}
catch (Exception ex)
{
return null;
}
}
调用
while (dr.Read())
{
mod = Class1.MapEntity<stuModel>(dr);
list.Add(mod);
}
当然,利用反射性能上,就会和之前的方法相距甚远,于是,我们可以把反射出来的属性值集合参数化,避免多次反射,其实结果都是一样的,在C#编程中,面向对象的思想很重要,减少代码冗余,增加代码重用率,参数化是经常用到的思想;
参数化后:
public static TEntity MapEntity<TEntity>(SqlDataReader reader, PropertyInfo[] properties) where TEntity : class, new()
{
try
{
// properties 为了避免多次反射,将其参数化,在C#编程中,应时刻有着面向对象的思想,而不是面向过程
//var properties = typeof(TEntity).GetProperties();
var entity = new TEntity();
foreach (var propertie in properties)
{
if (propertie.CanWrite)//判断属性是否可写
{
try
{
var index = reader.GetOrdinal(propertie.Name.Replace("_", ""));//列序号
var data = reader.GetValue(index);//指定列值
if (data != DBNull.Value)
{
if (propertie.PropertyType.IsGenericType && propertie.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
propertie.SetValue(entity, Convert.ChangeType(data, propertie.PropertyType.GetGenericArguments()[0]), null);
}
else
{
propertie.SetValue(entity, Convert.ChangeType(data, propertie.PropertyType), null);
}
}
}
catch (IndexOutOfRangeException ex)
{
continue;
}
}
}
return entity;
}
catch (Exception ex)
{
return null;
}
}
参数化后调用:
var properties = typeof(stuModel).GetProperties();
while (dr.Read())
{
mod = Class1.MapEntity<stuModel>(dr,properties);
list.Add(mod);
}