Datatable和实体集合互转

1.使用已废弃的 JavaScriptSerializer,且反序列化为弱类型 ArrayList。可用但不推荐。

csharp 复制代码
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字符串转换为DataTable
        public 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();
        }

        // 将泛型列表转换为DataTable
        public 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;
        }

        // 将泛型模型转换为DataRow
        public 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,支持复杂结构和动态类型。推荐

csharp 复制代码
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字符串转换为DataTable
        public 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; // 跳过非可空值类型的DBNull
                        value = 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();
        }

        // 将泛型列表转换为DataTable
        public 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);
        }
    }
}
相关推荐
玩泥巴的6 小时前
存储那么贵,何不白嫖飞书云文件空间
c#·.net·二次开发·飞书
脑电信号要分类16 小时前
将多张图片拼接成一个pdf文件输出
pdf·c#·apache
njsgcs16 小时前
c# solidworks 折弯系数检查
开发语言·c#
格林威17 小时前
工业相机图像采集:Grab Timeout 设置建议——拒绝“假死”与“丢帧”的黄金法则
开发语言·人工智能·数码相机·计算机视觉·c#·机器视觉·工业相机
唐青枫18 小时前
C#.NET SignalR + Redis Backplane 深入解析:多节点部署与跨实例消息同步
c#·.net
FL16238631291 天前
[C#][winform]segment-anything分割万物部署onnx模型一键抠图演示
开发语言·c#
love530love1 天前
OpenClaw 手机直连配置全流程
人工智能·windows·python·智能手机·c#·agent·openclaw
bcbobo21cn1 天前
C# byte类型和byte数组的使用
开发语言·c#·字节数组·byte类型
月巴月巴白勺合鸟月半1 天前
一次PDF文件的处理(一)
pdf·c#
大鹏说大话2 天前
Java 锁膨胀机制深度解析:从偏向锁到重量级锁的进化之路
开发语言·c#