在實際開發過程中,或者是第三方公司提供的數據表結構,與我們系統中的實體類字段不對應,遇到這樣我們怎么處理呢?可能有人會說,在轉換時創建一個實體對象,對表里的數據逐行遍歷來實例化這個實體對象不就完了。的確沒錯,這方法可行,但是這個方法效率極低,遇到億萬數據的話那就要實例化億萬個對象,更要命的是還要對每個對象的字段逐一賦值,由此可見它的效率了。
今天我無意在網上看到了一大牛寫的一段代碼,讓我很感慨,現在我將它記錄下來,希望對以后開發過程中有所用。
先看一下我的實體類
/// <summary> /// 具體的實體類,和數據表中不同 /// </summary> public class Person { [DataField("user_name")]//表示數據庫表里面的字段 public string UserName { set; get; }//表示需要轉換成的字段 [DataField("pass_word")] public string PassWord { set; get; } }
具體在代碼中有注釋,下面是轉換類
[AttributeUsage(AttributeTargets.Property)] public sealed class DataFieldAttribute : Attribute { /// <summary> /// 表對應的字段名 /// </summary> public string ColumnName { set; get; } public DataFieldAttribute(string columnName) { ColumnName = columnName; } } public static class DataConvert<T> where T : new() { /// <summary> /// 將DataRow行轉換成Entity /// </summary> /// <param name="dr"></param> /// <returns></returns> public static T ToEntity(DataRow dr) { T entity = new T(); Type info = typeof(T); var members = info.GetMembers(); foreach (var mi in members) { if (mi.MemberType == MemberTypes.Property) { //讀取屬性上的DataField特性 object[] attributes = mi.GetCustomAttributes(typeof(DataFieldAttribute), true); foreach (var attr in attributes) { var dataFieldAttr = attr as DataFieldAttribute; if (dataFieldAttr != null) { var propInfo = info.GetProperty(mi.Name); if (dr.Table.Columns.Contains(dataFieldAttr.ColumnName)) { //根據ColumnName,將dr中的相對字段賦值給Entity屬性 propInfo.SetValue(entity, Convert.ChangeType(dr[dataFieldAttr.ColumnName], propInfo.PropertyType), null); } } } } } return entity; } /// <summary> /// 將DataTable轉換成Entity列表 /// </summary> /// <param name="dt"></param> /// <returns></returns> public static List<T> ToList(DataTable dt) { List<T> list = new List<T>(dt.Rows.Count); foreach (DataRow dr in dt.Rows) { list.Add(ToEntity(dr)); } return list; } }
調用代碼:
DataTable dt = new DataTable(); dt.Columns.Add("user_name"); dt.Columns.Add("pass_word");//這是表中的字段,現在需要將它們轉換為具體的實體類實例 dt.Rows.Add("kingtiger","1"); dt.Rows.Add("wangbiao", "2"); var users = DataConvert<Person>.ToList(dt); foreach (var user in users) { Response.Write(user.UserName + "," + user.PassWord); } for (int i = 0; i < dt.Rows.Count; i++) { Person p = DataConvert<Person>.ToEntity(dt.Rows[i]); Response.Write(p.UserName + "," + p.PassWord); }