DataTableToList.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. using Newtonsoft.Json;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel.DataAnnotations.Schema;
  5. using System.Data;
  6. using System.Linq;
  7. using System.Reflection;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace WMS.Util
  11. {
  12. public class DataTableToList<T> where T : new()
  13. {
  14. public static IList<T> ConvertToModel(DataTable dt)
  15. {
  16. // 定义集合
  17. IList<T> ts = new List<T>();
  18. // 获得此模型的类型
  19. Type type = typeof(T);
  20. string tempName = "";
  21. foreach (DataRow dr in dt.Rows)
  22. {
  23. T t = new T();
  24. // 获得此模型的公共属性
  25. PropertyInfo[] propertys = t.GetType().GetProperties();
  26. foreach (PropertyInfo pi in propertys)
  27. {
  28. tempName = pi.Name; // 检查DataTable是否包含此列
  29. if (dt.Columns.Contains(tempName))
  30. {
  31. // 判断此属性是否有Setter
  32. if (!pi.CanWrite) continue;
  33. object value = dr[tempName];
  34. if (value != DBNull.Value)
  35. pi.SetValue(t, value, null);
  36. }
  37. }
  38. ts.Add(t);
  39. }
  40. return ts;
  41. }
  42. }
  43. public static class DataTableExtension
  44. {
  45. public static List<T> ToList<T>(this DataTable dt, IRowMapper<T> rowMapper)
  46. {
  47. if (dt == null || dt.Rows.Count == 0)
  48. {
  49. return null;
  50. }
  51. List<T> entites = new List<T>();
  52. foreach (DataRow dr in dt.Rows)
  53. {
  54. var t = rowMapper.MapRow(dr);
  55. entites.Add(t);
  56. }
  57. return entites;
  58. }
  59. /// <summary>
  60. /// 可以直接使用newtonsoft进行序列化
  61. /// </summary>
  62. /// <typeparam name="T"></typeparam>
  63. /// <param name="dt"></param>
  64. /// <param name="rowMapper"></param>
  65. /// <returns></returns>
  66. public static string ToJson<T>(this DataTable dt, IRowMapper<T> rowMapper)
  67. {
  68. if (dt == null || dt.Rows.Count == 0)
  69. {
  70. return null;
  71. }
  72. StringBuilder strBuilder = new StringBuilder("[");
  73. foreach (DataRow dr in dt.Rows)
  74. {
  75. var t = rowMapper.MapRow(dr);
  76. strBuilder.Append(t + ",");
  77. }
  78. strBuilder.Remove(strBuilder.Length - 1, 1);
  79. strBuilder.Append("]");
  80. return strBuilder.ToString();
  81. }
  82. }
  83. public class ColumnAttributeMapper<T> : IRowMapper<T>
  84. {
  85. private Dictionary<string, Dictionary<string, string>> ColumnPropertyMapper = new Dictionary<string, Dictionary<string, string>>();
  86. public ColumnAttributeMapper()
  87. {
  88. if (!ColumnPropertyMapper.ContainsKey(typeof(T).Name))
  89. {
  90. Dictionary<string, string> dict = new Dictionary<string, string>();
  91. var props = typeof(T).GetProperties();
  92. foreach (var prop in props)
  93. {
  94. var attribute = prop.GetCustomAttributes(true).OfType<ColumnAttribute>().FirstOrDefault();
  95. dict.Add(attribute.Name, prop.Name);
  96. }
  97. ColumnPropertyMapper.Add(typeof(T).Name, dict);
  98. }
  99. }
  100. public T MapRow(DataRow dr)
  101. {
  102. T t = (T)Activator.CreateInstance(typeof(T));
  103. for (int i = 0; i < dr.Table.Columns.Count; i++)
  104. {
  105. if (ColumnPropertyMapper.ContainsKey(t.GetType().Name))
  106. {
  107. var dict = ColumnPropertyMapper[t.GetType().Name];
  108. var property = dict[dr.Table.Columns[i].ColumnName];
  109. PropertyInfo propertyInfo = t.GetType().GetProperty(property);
  110. if (propertyInfo != null && dr[i] != DBNull.Value)
  111. propertyInfo.SetValue(t, dr[i], null);
  112. }
  113. }
  114. return t;
  115. }
  116. }
  117. /// <summary>
  118. /// 将查询结果映射为对象
  119. /// </summary>
  120. /// <typeparam name="TResult"></typeparam>
  121. public interface IRowMapper<out TResult>
  122. {
  123. /// <summary>
  124. /// When implemented by a class, returns a new TResult based on row.
  125. /// </summary>
  126. /// <param name="row"> The System.Data.IDataRecord to map.</param>
  127. /// <returns>The instance of TResult that is based on row.</returns>
  128. TResult MapRow(DataRow dr);
  129. /// <summary>
  130. /// 增加自定义转换,todo 复杂列(eee#bb)转换
  131. /// </summary>
  132. /// <param name="convert"></param>
  133. //void AddCustomConverter(Converter convert);
  134. /// <summary>
  135. /// 表信息,每个数据库一个
  136. /// </summary>
  137. //TablesInfo TablesInfo { get; set; }
  138. }
  139. public class ColumnConverter
  140. {
  141. public string ColumnName { get; set; }
  142. public string PropertyPath { get; set; }
  143. /// <summary>
  144. /// 数据库值转换为对象值
  145. /// </summary>
  146. public Func<object> Convert { get; set; }
  147. }
  148. public class JsonMapper : IRowMapper<StringBuilder>
  149. {
  150. public StringBuilder MapRow(DataRow dr)
  151. {
  152. StringBuilder strBuilder = new StringBuilder();
  153. StringWriter strWriter = new StringWriter(strBuilder);
  154. using (JsonWriter writer = new JsonTextWriter(strWriter))
  155. {
  156. writer.WriteStartObject();
  157. foreach (var col in dr.Table.Columns)
  158. {
  159. var value = dr.Field<object>(col.ToString());
  160. writer.WritePropertyName(col.ToString());
  161. writer.WriteValue(value);
  162. }
  163. writer.WriteEndObject();
  164. }
  165. return strBuilder;
  166. }
  167. }
  168. public class ColumnAttribute : Attribute
  169. {
  170. public string Name { get; set; }
  171. public ColumnAttribute(string fieldName)
  172. {
  173. this.Name = fieldName;
  174. }
  175. }
  176. }