Datatable和实体集合互转
1.使用已废弃的 JavaScriptSerializer,且反序列化为弱类型 ArrayList。可用但不推荐。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Script.Serialization;namespace Helper
{public static class DataTableHelper{// 将JSON字符串转换为DataTablepublic static DataTable JsonToDataTable(string json){DataTable dataTable = new DataTable();try{JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();javaScriptSerializer.MaxJsonLength = Int32.MaxValue;ArrayList arrayList = javaScriptSerializer.Deserialize<ArrayList>(json);if (arrayList.Count > 0){foreach (Dictionary<string, object> dic in arrayList){if (dic.Keys.Count == 0) return dataTable;if (dataTable.Columns.Count == 0){foreach (string current in dic.Keys){Type tp = dic[current]?.GetType() ?? typeof(string);dataTable.Columns.Add(current, tp);}}DataRow datarow = dataTable.NewRow();foreach (string current in dic.Keys){datarow[current] = dic[current] ?? DBNull.Value;}dataTable.Rows.Add(datarow);}}}catch { }return dataTable;}// 将DataTable转换为泛型实体列表public static List<T> ConvertToEntity<T>(this DataTable table) where T : new(){List<T> list = new List<T>();foreach (DataRow row in table.Rows){T entity = new T();foreach (PropertyInfo prop in typeof(T).GetProperties()){if (table.Columns.Contains(prop.Name.ToUpper())){object value = row[prop.Name.ToUpper()];if (value != DBNull.Value){// 处理decimal/double转string的特殊情况if ((prop.PropertyType == typeof(string)) &&(value is decimal || value is double)){prop.SetValue(entity, Convert.ChangeType(value, prop.PropertyType));}else if ((prop.PropertyType == typeof(int) || prop.PropertyType == typeof(long)) &&(value is decimal || value is double)){prop.SetValue(entity, Convert.ChangeType(value, prop.PropertyType));}else{prop.SetValue(entity, value);}}}}list.Add(entity);}return list;}// 将DataRow转换为泛型实体public static T ConvertToEntity<T>(this DataRow row) where T : new(){DataTable dt = new DataTable();dt.Rows.Add(row);return ConvertToEntity<T>(dt).FirstOrDefault();}// 将泛型列表转换为DataTablepublic static DataTable ConvertToDataTable<T>(this List<T> list){DataTable table = new DataTable();if (list == null || list.Count == 0) return table;foreach (PropertyInfo prop in typeof(T).GetProperties()){table.Columns.Add(prop.Name.ToUpper(),Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);}foreach (T entity in list){DataRow row = table.NewRow();foreach (PropertyInfo prop in typeof(T).GetProperties()){object value = prop.GetValue(entity, null);row[prop.Name.ToUpper()] = value ?? DBNull.Value;}table.Rows.Add(row);}return table;}// 将泛型模型转换为DataRowpublic static DataRow ConvertToDataRow<T>(this T model){DataTable table = new DataTable();if (model == null) return null;foreach (PropertyInfo prop in typeof(T).GetProperties()){table.Columns.Add(prop.Name.ToUpper(),Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);}DataRow row = table.NewRow();foreach (PropertyInfo prop in typeof(T).GetProperties()){object value = prop.GetValue(model, null);row[prop.Name.ToUpper()] = value ?? DBNull.Value;}table.Rows.Add(row);return table.Rows[0];}}
}
2.使用 Newtonsoft.Json.Linq.JArray 解析 JSON,支持复杂结构和动态类型。推荐
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;namespace Helper
{public static class DataTableHelper{// 将JSON字符串转换为DataTablepublic static DataTable JsonToDataTable(string json){var dataTable = new DataTable();try{var jsonArray = JArray.Parse(json);if (jsonArray.Count == 0) return dataTable;// 初始化列var firstItem = jsonArray.First.ToObject<Dictionary<string, object>>();foreach (var key in firstItem.Keys){dataTable.Columns.Add(key, GetDataType(firstItem[key]));}// 填充数据foreach (var item in jsonArray){var row = dataTable.NewRow();foreach (var key in item.Properties()){var columnName = key.Name;var value = key.Value?.ToString() ?? DBNull.Value;row[columnName] = ConvertValue(value, dataTable.Columns[columnName].DataType);}dataTable.Rows.Add(row);}}catch (Exception ex){// 记录异常(实际项目中使用日志组件)Console.WriteLine($"JSON转DataTable失败: {ex.Message}");}return dataTable;}// 将DataTable转换为泛型实体列表public static List<T> ConvertToEntity<T>(this DataTable table) where T : new(){var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList();var list = new List<T>();foreach (DataRow row in table.Rows){var entity = new T();foreach (var prop in properties){if (!table.Columns.Contains(prop.Name) && !table.Columns.Contains(prop.Name.ToUpper()))continue;var columnName = table.Columns[prop.Name] != null ? prop.Name : table.Columns.Cast<DataColumn>().FirstOrDefault(c => c.ColumnName.Equals(prop.Name, StringComparison.OrdinalIgnoreCase))?.ColumnName;if (columnName == null) continue;var value = row[columnName];if (value == DBNull.Value){if (prop.PropertyType.IsValueType && Nullable.GetUnderlyingType(prop.PropertyType) == null)continue; // 跳过非可空值类型的DBNullvalue = null;}try{prop.SetValue(entity, Convert.ChangeType(value, prop.PropertyType));}catch (Exception ex){Console.WriteLine($"属性 {prop.Name} 转换失败: {ex.Message}");}}list.Add(entity);}return list;}// 将DataRow转换为泛型实体public static T ConvertToEntity<T>(this DataRow row) where T : new(){var dt = new DataTable();dt.Rows.Add(row.ItemArray);return dt.ConvertToEntity<T>().FirstOrDefault();}// 将泛型列表转换为DataTablepublic static DataTable ConvertToDataTable<T>(this List<T> list){if (list == null || list.Count == 0) return new DataTable();var dataTable = new DataTable();var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);foreach (var prop in properties){dataTable.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);}foreach (var entity in list){var row = dataTable.NewRow();foreach (var prop in properties){var value = prop.GetValue(entity) ?? DBNull.Value;row[prop.Name] = value;}dataTable.Rows.Add(row);}return dataTable;}// 辅助方法:获取值的类型private static Type GetDataType(object value){if (value == null) return typeof(string);return value.GetType();}// 辅助方法:安全转换值类型private static object ConvertValue(object value, Type targetType){if (value == DBNull.Value) return null;if (targetType.IsEnum)return Enum.Parse(targetType, value.ToString());if (targetType == typeof(DateTime) && value is string str)return DateTime.Parse(str);return Convert.ChangeType(value, targetType);}}
}