前言,此方法利用反射将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
时间: 2024-10-26 08:48:59