DataTable transforms into entity
Because the query function of Linq is very powerful, I will convert the data from the database to entity collection List for convenience.
At first, it is hard-coded, easy to understand, but very low in generality. here is the code in the control console:
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 Demo1 9 {10 class Program11 {12 static void Main (string [] args) 13 {14 DataTable dt = Query (); 15 List usrs = new List (dt.Rows.Count) 16 / / hard-coded, efficient but not flexible enough. If the entity changes, you need to modify the code 17 foreach (DataRow dr in dt.Rows) 18 {19 Usr usr = new Usr {ID = dr.Field ("ID"), Name = dr.Field ("Name")}; 20 usrs.Add (usr) 21} 22 usrs.Clear (); 23} 24 25 / / 26 / / query data 27 / / 28 / 29 private static DataTable Query () 30 {31 DataTable dt = new DataTable (); 32 dt.Columns.Add ("ID", typeof (Int32)) 33 dt.Columns.Add ("Name", typeof (String)); 34 for (int I = 0; I
< 1000000; i++)35 {36 dt.Rows.Add(new Object[] { i, Guid.NewGuid().ToString() });37 }38 return dt;39 }40 }41 class Usr42 {43 public Int32? ID { get; set; }44 public String Name { get; set; }45 }46 } 后来用反射来做这,对实体的属性用反射去赋值,这样就可以对所有的实体通用,且增加属性后不用修改代码。 程序如下: 1 static class EntityConvert 2 { 3 /// 4 /// DataTable转为List 5 /// 6 /// 7 /// 8 /// 9 public static List ToList(this DataTable dt) where T : class, new()10 {11 List colletion = new List();12 PropertyInfo[] pInfos = typeof(T).GetProperties();13 foreach (DataRow dr in dt.Rows)14 {15 T t = new T();16 foreach (PropertyInfo pInfo in pInfos)17 {18 if (!pInfo.CanWrite) continue;19 pInfo.SetValue(t, dr[pInfo.Name]);20 }21 colletion.Add(t);22 }23 return colletion;24 }25 } 增加一个扩展方法,程序更加通用。但效率不怎么样,100万行数据【只有两列】,转换需要2秒 后来想到用委托去做 委托原型如下 1 Func func = dr =>New Usr {ID = dr.Field ("ID"), Name = dr.Field ("Name")}
The code is as follows:
1 static void Main (string [] args) 2 {3 DataTable dt = Query (); 4 Func func = dr = > new Usr {ID = dr.Field ("ID"), Name = dr.Field ("Name")}; 5 List usrs = new List (dt.Rows.Count); 6 Stopwatch sw = Stopwatch.StartNew () 7 foreach (DataRow dr in dt.Rows) 8 {9 Usr usr = func (dr); 10 usrs.Add (usr); 11} 12 sw.Stop (); 13 Console.WriteLine (sw.ElapsedMilliseconds); 14 usrs.Clear (); 15 Console.ReadKey (); 16}
The speed is really much faster. I tested it on my computer and it takes 0.4 seconds. But here comes the problem again. This can only be used for the class Usr. We have to find a way to abstract this class into a generic T, which has both the efficiency of delegation and the
Generics are generic.
The problem lies in the dynamic generation of the above delegation, after a whole afternoon of twists and turns finally came out of the method of dynamic generation of delegation. Dynamic Lambda expressions are mainly used
1 public static class EntityConverter 2 {3 / 4 / DataTable generating entity 5 / 6 / 7 / 8 / / 9 public static List ToList (this DataTable dataTable) where T: class, new () 10 {11 if (dataTable = = null | | dataTable.Rows.Count