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);
        }
    }
}
相关推荐
m5655bj4 分钟前
如何通过 C# 快速生成二维码 QR Code
c#·visual studio
浩子智控40 分钟前
开源RPA选择
python·c#·软件工程
缺点内向1 小时前
C#: 如何自动化创建Word可填写表单,告别手动填写时代
c#·自动化·word
阿蒙Amon1 小时前
C#每日面试题-Array和List的区别
面试·c#
SunnyDays10111 小时前
如何使用 C# 将 PDF 转换为 SVG:完整指南
c#·pdf转svg
Lv11770081 小时前
Visual Studio中的正则表达式
ide·笔记·正则表达式·c#·visual studio
唐青枫2 小时前
C#.NET ConcurrentDictionary<TKey, TValue> 深度解析:原理与实践
c#·.net
小先生8122 小时前
关于vue-element-plus-admin的mini分支踩坑集锦
前端·vue.js·前端框架·c#
唐宋元明清218810 小时前
.NET 磁盘管理-技术方案选型
windows·c#·存储
故事不长丨10 小时前
C#正则表达式完全攻略:从基础到实战的全场景应用指南
开发语言·正则表达式·c#·regex