标签:style blog io color os ar for sp 数据
最近做项目实现了自动将DataTable对象中的数据转化为制定Model类型对象列表的功能,这里做记录:
首先是定义转化类 :
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Linq; 6 using System.Reflection; 7 using System.Text; 8 using System.Threading.Tasks; 9 10 namespace ClassView 11 { 12 /// <summary> 13 /// 进行从 DataTable 或者实现 IDataReader 接口的对象读取记录 14 /// 并将结果集转换为给定类型列表的方法。 15 /// </summary> 16 public class ModelConvetor 17 { 18 /// <summary> 19 /// 从 reader 对象中逐行读取记录并将记录转化为 T 类型的集合 20 /// </summary> 21 /// <typeparam name="T">目标类型参数</typeparam> 22 /// <param name="reader">实现 IDataReader 接口的对象。</param> 23 /// <returns>指定类型的对象集合。</returns> 24 public static List<T> ConvertToObject<T>(IDataReader reader) 25 where T : class 26 { 27 List<T> list = new List<T>(); 28 T obj = default(T); 29 Type t = typeof(T); 30 Assembly ass = t.Assembly; 31 32 Dictionary<string, PropertyInfo> propertys = ModelConvetor.GetFields<T>(reader); 33 PropertyInfo p = null; 34 if (reader != null) 35 { 36 while (reader.Read()) 37 { 38 obj = ass.CreateInstance(t.FullName) as T; 39 foreach (string key in propertys.Keys) 40 { 41 p = propertys[key]; 42 p.SetValue(obj, ModelConvetor.ChangeType(reader[key], p.PropertyType)); 43 } 44 list.Add(obj); 45 } 46 } 47 48 return list; 49 } 50 51 /// <summary> 52 /// 从 DataTale 对象中逐行读取记录并将记录转化为 T 类型的集合 53 /// </summary> 54 /// <typeparam name="T">目标类型参数</typeparam> 55 /// <param name="reader">DataTale 对象。</param> 56 /// <returns>指定类型的对象集合。</returns> 57 public static List<T> ConvertToObject<T>(DataTable table) 58 where T : class 59 { 60 return table == null 61 ? new List<T>() 62 : ModelConvetor.ConvertToObject<T>(table.CreateDataReader() as IDataReader); 63 } 64 65 /// <summary> 66 /// 将数据转化为 type 类型 67 /// </summary> 68 /// <param name="value">要转化的值</param> 69 /// <param name="type">目标类型</param> 70 /// <returns>转化为目标类型的 Object 对象</returns> 71 private static object ChangeType(object value, Type type) 72 { 73 if (type.FullName == typeof(string).FullName) 74 { 75 return Convert.ChangeType(Convert.IsDBNull(value) ? null : value, type); 76 } 77 if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) 78 { 79 NullableConverter convertor = new NullableConverter(type); 80 return Convert.IsDBNull(value) ? null : convertor.ConvertFrom(value); 81 } 82 return value; 83 } 84 85 /// <summary> 86 /// 获取reader存在并且在 T 类中包含同名可写属性的集合 87 /// </summary> 88 /// <param name="reader"> 89 /// 可写域的集合 90 /// </param> 91 /// <returns> 92 /// 以属性名为键,PropertyInfo 为值得字典对象 93 /// </returns> 94 private static Dictionary<string, PropertyInfo> GetFields<T>(IDataReader reader) 95 { 96 Dictionary<string, PropertyInfo> result = new Dictionary<string, PropertyInfo>(); 97 int columnCount = reader.FieldCount; 98 Type t = typeof(T); 99 100 PropertyInfo[] properties = t.GetProperties(); 101 if (properties != null) 102 { 103 List<string> readerFields = new List<string>(); 104 for (int i = 0; i < columnCount; i++) 105 { 106 readerFields.Add(reader.GetName(i)); 107 } 108 IEnumerable<PropertyInfo> resList = 109 (from PropertyInfo prop in properties 110 where prop.CanWrite && readerFields.Contains(prop.Name) 111 select prop); 112 113 foreach (PropertyInfo p in resList) 114 { 115 result.Add(p.Name, p); 116 } 117 } 118 return result; 119 } 120 } 121 }
接下来是测试类型:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace ClassView 8 { 9 public class TestObj 10 { 11 public int? UserID { get; set; } 12 public string UserName { get; set; } 13 public decimal? Height { get; set; } 14 public DateTime? Birthday { get; set; } 15 } 16 }
最后是测试代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Data; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace ClassView 9 { 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 DataTable table = new DataTable(); 15 table.Columns.AddRange(new DataColumn[] 16 { 17 new DataColumn("UserID"), 18 new DataColumn("UserName"), 19 new DataColumn("Height"), 20 new DataColumn("Birthday") 21 }); 22 for (int i = 0; i < 10; i++) 23 { 24 DataRow row = table.NewRow(); 25 row["UserID"] = i % 2 == 0 ? DBNull.Value : i as object; 26 row["UserName"] = "User" + i; 27 row["Height"] = i % 5 == 0 ? DBNull.Value : (i + 5) as object; 28 row["Birthday"] = i % 3 == 0 ? DBNull.Value : (DateTime.Now) as object; 29 table.Rows.Add(row); 30 } 31 List<TestObj> res = ModelConvetor.ConvertToObject<TestObj>(table); 32 foreach (TestObj o in res) 33 { 34 Console.WriteLine(string.Format("UserID:{0}",o.UserID)); 35 Console.WriteLine(string.Format("UserName:{0}", o.UserName)); 36 Console.WriteLine(string.Format("Height:{0}", o.Height)); 37 Console.WriteLine(string.Format("Birthday:{0}", o.Birthday)); 38 Console.WriteLine("-------------------------------------------------------------------------"); 39 } 40 Console.ReadLine(); 41 } 42 } 43 }
执行结果如下:
下次是配置数据库代码,to be continue ...
标签:style blog io color os ar for sp 数据
原文地址:http://www.cnblogs.com/lee2014/p/4067594.html