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);
        }
    }
}
相关推荐
shangjg32 小时前
Kafka 如何保证顺序消费
c#·linq
FuckPatience2 小时前
C# 关于闭包与多线程结合使用
c#
半青年3 小时前
IEC61850规约客户端软件开发实战(第二章)
java·c++·qt·网络协议·c#·信息与通信·iec61850
TA远方3 小时前
【C#】一个简单的http服务器项目开发过程详解
服务器·http·c#·wpf·web·winform·console
CodeCraft Studio3 小时前
国产化Excel处理组件Spire.XLS教程:如何使用 C# 将 Excel(XLS 或 XLSX)文件转换为 PDF
pdf·c#·excel
招财进宝。。3 小时前
c# 获取电脑 分辨率 及 DPI 设置
开发语言·c#·电脑
zybsjn5 小时前
后端项目中静态文案国际化语言包构建选型
java·后端·c#
vvilkim5 小时前
深入理解C#异步编程:原理、实践与最佳方案
服务器·开发语言·c#
阿蒙Amon8 小时前
C#数字金额转中文大写金额:代码解析
java·mysql·c#
程序猿多布10 小时前
C# 密封类和密封方法
c#