DataTable转list

2019-09-29 17:44:01 浏览数 (3)

代码语言: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         }

0 人点赞