前言,此方法利用反射將DataRow轉成實體,由於反射SetValue據說性能不行,大家就看看就行了吧。 後話, 1.可以通過緩存提高下性能。 每次typeof(T)後,將其對象相關信息(泛型屬性等)存儲起來,下次從緩存讀取。 2.對SetValue改進。 可以使用泛型委托對其賦值。 3.用Emit ...
前言,此方法利用反射將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 { //值類型 Struct, Enum, //引用類型 String, Object, Else } private static ModelType GetModelType(Type modelType) { if (modelType.IsEnum)//值類型 { return ModelType.Enum; } if (modelType.IsValueType)//值類型 { return ModelType.Struct; } else if (modelType == typeof(string))//引用類型 特殊類型處理 { return ModelType.String; } else if (modelType == typeof(object))//引用類型 特殊類型處理 { return ModelType.Object; } else//引用類型 { return ModelType.Else; } } 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.Struct://值類型 { model = default(T); if (row[0] != null) model = (T)row[0]; } break; case ModelType.Enum://值類型 { model = default(T); if (row[0] != null) { Type fiType = row[0].GetType(); if (fiType == typeof(int)) { model = (T)row[0]; } else if (fiType == typeof(string)) { model = (T)Enum.Parse(typeof(T), row[0].ToString()); } } } 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.Else://引用類型 { 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) && row[name] != null) { ModelType piType = GetModelType(pi.PropertyType); switch (piType) { case ModelType.Struct: { var value = Convert.ChangeType(row[name], pi.PropertyType); pi.SetValue(model, value, null); } break; case ModelType.Enum: { Type fiType = row[0].GetType(); if (fiType == typeof(int)) { pi.SetValue(model, row[name], null); } else if (fiType == typeof(string)) { var value = (T)Enum.Parse(typeof(T), row[name].ToString()); if (value != null) pi.SetValue(model, value, null); } } break; case ModelType.String: { var value = Convert.ChangeType(row[name], pi.PropertyType); pi.SetValue(model, value, null); } break; case ModelType.Object: { pi.SetValue(model, row[name], null); } break; case ModelType.Else: throw new Exception("不支持該類型轉換"); default: throw new Exception("未知類型"); } } } #endregion } break; default: model = default(T); break; } return model; } } }
後話,
1.可以通過緩存提高下性能。
每次typeof(T)後,將其對象相關信息(泛型屬性等)存儲起來,下次從緩存讀取。
2.對SetValue改進。
可以使用泛型委托對其賦值。
3.用Emit