你的位置:首页 > ASP.net教程

[ASP.net教程]DataRow转泛型,利用反射将查询数据直接转成实体


前言,此方法利用反射将DataRow转成实体,由于反射SetValue据说性能不行,大家就看看就行了吧。

using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Reflection;using System.Text;namespace WangSql.DBUtility{  public class DataMapHelper  {    private enum ModelType    {      Value,      String,      Object,      Reference    }    private static ModelType GetModelType(Type modelType)    {      if (modelType.IsValueType)//值类型      {        return ModelType.Value;      }      else if (modelType == typeof(string))//引用类型 特殊类型处理      {        return ModelType.String;      }      else if (modelType == typeof(object))//引用类型 特殊类型处理      {        return ModelType.Object;      }      else//引用类型      {        return ModelType.Reference;      }    }    public static List<T> DataTableToList<T>(DataTable table)    {      List<T> list = new List<T>();      foreach (DataRow item in table.Rows)      {        list.Add(DataRowToModel<T>(item));      }      return list;    }    public static T DataRowToModel<T>(DataRow row)    {      T model;      Type type = typeof(T);      ModelType modelType = GetModelType(type);      switch (modelType)      {        case ModelType.Value://值类型          {            model = default(T);            if (row[0] != null)              model = (T)row[0];          }          break;        case ModelType.String://引用类型 c#对string也当做值类型处理          {            model = default(T);            if (row[0] != null)              model = (T)row[0];          }          break;        case ModelType.Object://引用类型 直接返回第一行第一列的值          {            model = default(T);            if (row[0] != null)              model = (T)row[0];          }          break;        case ModelType.Reference://引用类型          {            model = System.Activator.CreateInstance<T>();//引用类型 必须对泛型实例化            #region MyRegion            //获取model中的属性            PropertyInfo[] modelPropertyInfos = type.GetProperties();            //遍历model每一个属性并赋值DataRow对应的列            foreach (PropertyInfo pi in modelPropertyInfos)            {              //获取属性名称              String name = pi.Name;              if (row.Table.Columns.Contains(name))              {                //非泛型                if (!pi.PropertyType.IsGenericType)                {                  if (pi.PropertyType.IsEnum)                  {                    pi.SetValue(model, row[name], null);                  }                  else                  {                    pi.SetValue(model, string.IsNullOrEmpty(row[name].ToString()) ? null : Convert.ChangeType(row[name], pi.PropertyType), null);                  }                }                //泛型Nullable<>                else                {                  Type genericTypeDefinition = pi.PropertyType.GetGenericTypeDefinition();                  //model属性是可为null类型,进行赋null值                  if (genericTypeDefinition == typeof(Nullable<>))                  {                    //返回指定可以为 null 的类型的基础类型参数                    pi.SetValue(model, string.IsNullOrEmpty(row[name].ToString()) ? null : Convert.ChangeType(row[name], Nullable.GetUnderlyingType(pi.PropertyType)), null);                  }                }              }            }            #endregion          }          break;        default:          model = default(T);          break;      }      return model;    }  }}

 

后话,

1.可以通过缓存提高下性能。

   每次typeof(T)后,将其对象相关信息(泛型属性等)存储起来,下次从缓存读取。

2.对SetValue改进。

   可以使用泛型委托对其赋值。

3.用Emit