前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DataTable转list

DataTable转list

作者头像
用户6362579
发布2019-09-29 17:44:01
1.6K0
发布2019-09-29 17:44:01
举报
文章被收录于专栏:小神仙小神仙
代码语言:javascript
复制
 1 public static class EntityConverter
 2 {
 3     /// <summary>
 4     /// DataTable生成实体
 5     /// </summary>
 6     /// <typeparam name="T"></typeparam>
 7     /// <param name="dataTable"></param>
 8     /// <returns></returns>
 9     public static IEnumerable<T> ToList<T>(this DataTable dataTable) where T : class, new()
10     {
11         if (dataTable == null)
12             throw new ArgumentNullException(nameof(dataTable));
13 
14         List<T> collection = new List<T>(dataTable.Rows.Count);
15         if (dataTable.Rows.Count == 0)
16         {
17             return collection;
18         }
19         Func<DataRow, T> func = ToExpression<T>(dataTable.Rows[0]);
20 
21         foreach (DataRow dr in dataTable.Rows)
22         {
23             collection.Add(func(dr));
24         }
25         return collection;
26     }
27 
28     /// <summary>
29     /// 生成表达式
30     /// </summary>
31     /// <typeparam name="T"></typeparam>
32     /// <param name="dataRow"></param>
33     /// <returns></returns>
34     public static Func<DataRow, T> ToExpression<T>(DataRow dataRow) where T : class, new()
35     {
36         if (dataRow == null) throw new ArgumentNullException("dataRow", "当前对象为null 无法转换成实体");
37         ParameterExpression paramter = Expression.Parameter(typeof(DataRow), "dr");
38         List<MemberBinding> binds = new List<MemberBinding>();
39         for (int i = 0; i < dataRow.ItemArray.Length; i++)
40         {
41             String colName = dataRow.Table.Columns[i].ColumnName;
42             PropertyInfo pInfo = typeof(T).GetProperty(colName);
43             if (pInfo == null) continue;
44             MethodInfo mInfo = typeof(DataRowExtensions).GetMethod("Field", new Type[] { typeof(DataRow), typeof(String) }).MakeGenericMethod(pInfo.PropertyType);
45             MethodCallExpression call = Expression.Call(mInfo, paramter, Expression.Constant(colName, typeof(String)));
46             MemberAssignment bind = Expression.Bind(pInfo, call);
47             binds.Add(bind);
48         }
49         MemberInitExpression init = Expression.MemberInit(Expression.New(typeof(T)), binds.ToArray());
50         return Expression.Lambda<Func<DataRow, T>>(init, paramter).Compile();
51     }
52 }

list转datatable

代码语言:javascript
复制
  1     public class ObjectShredder<T>
  2     {
  3         private System.Reflection.FieldInfo[] _fi;
  4         private System.Reflection.PropertyInfo[] _pi;
  5         private System.Collections.Generic.Dictionary<string, int> _ordinalMap;
  6         private System.Type _type;
  7 
  8         // ObjectShredder constructor.
  9         public ObjectShredder()
 10         {
 11             _type = typeof(T);
 12             _fi = _type.GetFields();
 13             _pi = _type.GetProperties();
 14             _ordinalMap = new Dictionary<string, int>();
 15         }
 16 
 17         /// <summary>
 18         /// Loads a DataTable from a sequence of objects.
 19         /// </summary>
 20         /// <param name="source">The sequence of objects to load into the DataTable.</param>
 21         /// <param name="table">The input table. The schema of the table must match that 
 22         /// the type T.  If the table is null, a new table is created with a schema 
 23         /// created from the public properties and fields of the type T.</param>
 24         /// <param name="options">Specifies how values from the source sequence will be applied to 
 25         /// existing rows in the table.</param>
 26         /// <returns>A DataTable created from the source sequence.</returns>
 27         public DataTable Shred(IEnumerable<T> source, DataTable table, LoadOption? options)
 28         {
 29             // Load the table from the scalar sequence if T is a primitive type.
 30             if (typeof(T).IsPrimitive)
 31             {
 32                 return ShredPrimitive(source, table, options);
 33             }
 34 
 35             // Create a new table if the input table is null.
 36             if (table == null)
 37             {
 38                 table = new DataTable(typeof(T).Name);
 39             }
 40 
 41             // Initialize the ordinal map and extend the table schema based on type T.
 42             table = ExtendTable(table, typeof(T));
 43 
 44             // Enumerate the source sequence and load the object values into rows.
 45             table.BeginLoadData();
 46             using (IEnumerator<T> e = source.GetEnumerator())
 47             {
 48                 while (e.MoveNext())
 49                 {
 50                     if (options != null)
 51                     {
 52                         table.LoadDataRow(ShredObject(table, e.Current), (LoadOption)options);
 53                     }
 54                     else
 55                     {
 56                         table.LoadDataRow(ShredObject(table, e.Current), true);
 57                     }
 58                 }
 59             }
 60             table.EndLoadData();
 61 
 62             // Return the table.
 63             return table;
 64         }
 65 
 66         public DataTable ShredPrimitive(IEnumerable<T> source, DataTable table, LoadOption? options)
 67         {
 68             // Create a new table if the input table is null.
 69             if (table == null)
 70             {
 71                 table = new DataTable(typeof(T).Name);
 72             }
 73 
 74             if (!table.Columns.Contains("Value"))
 75             {
 76                 table.Columns.Add("Value", typeof(T));
 77             }
 78 
 79             // Enumerate the source sequence and load the scalar values into rows.
 80             table.BeginLoadData();
 81             using (IEnumerator<T> e = source.GetEnumerator())
 82             {
 83                 Object[] values = new object[table.Columns.Count];
 84                 while (e.MoveNext())
 85                 {
 86                     values[table.Columns["Value"].Ordinal] = e.Current;
 87 
 88                     if (options != null)
 89                     {
 90                         table.LoadDataRow(values, (LoadOption)options);
 91                     }
 92                     else
 93                     {
 94                         table.LoadDataRow(values, true);
 95                     }
 96                 }
 97             }
 98             table.EndLoadData();
 99 
100             // Return the table.
101             return table;
102         }
103 
104         public object[] ShredObject(DataTable table, T instance)
105         {
106 
107             FieldInfo[] fi = _fi;
108             PropertyInfo[] pi = _pi;
109 
110             if (instance.GetType() != typeof(T))
111             {
112                 // If the instance is derived from T, extend the table schema
113                 // and get the properties and fields.
114                 ExtendTable(table, instance.GetType());
115                 fi = instance.GetType().GetFields();
116                 pi = instance.GetType().GetProperties();
117             }
118 
119             // Add the property and field values of the instance to an array.
120             Object[] values = new object[table.Columns.Count];
121             foreach (FieldInfo f in fi)
122             {
123                 values[_ordinalMap[f.Name]] = f.GetValue(instance);
124             }
125 
126             foreach (PropertyInfo p in pi)
127             {
128                 values[_ordinalMap[p.Name]] = p.GetValue(instance, null);
129             }
130 
131             // Return the property and field values of the instance.
132             return values;
133         }
134 
135         public DataTable ExtendTable(DataTable table, Type type)
136         {
137             // Extend the table schema if the input table was null or if the value 
138             // in the sequence is derived from type T.            
139             foreach (FieldInfo f in type.GetFields())
140             {
141                 if (!_ordinalMap.ContainsKey(f.Name))
142                 {
143                     // Add the field as a column in the table if it doesn't exist
144                     // already.
145                     DataColumn dc = table.Columns.Contains(f.Name) ? table.Columns[f.Name]
146                         : table.Columns.Add(f.Name, f.FieldType);
147 
148                     // Add the field to the ordinal map.
149                     _ordinalMap.Add(f.Name, dc.Ordinal);
150                 }
151             }
152             foreach (PropertyInfo p in type.GetProperties())
153             {
154                 if (!_ordinalMap.ContainsKey(p.Name))
155                 {
156                     // Add the property as a column in the table if it doesn't exist
157                     // already.
158                     DataColumn dc = table.Columns.Contains(p.Name) ? table.Columns[p.Name]
159                         : table.Columns.Add(p.Name, p.PropertyType);
160 
161                     // Add the property to the ordinal map.
162                     _ordinalMap.Add(p.Name, dc.Ordinal);
163                 }
164             }
165 
166             // Return the table.
167             return table;
168         }
169     }
代码语言:javascript
复制
 1         public static DataTable CopyToDataTable<T>(this IEnumerable<T> source)
 2         {
 3             return new ObjectShredder<T>().Shred(source, null, null);
 4         }
 5 
 6         public static DataTable CopyToDataTable<T>(this IEnumerable<T> source,
 7                                                     DataTable table, LoadOption? options)
 8         {
 9             return new ObjectShredder<T>().Shred(source, table, options);
10         }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-11-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档