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字符串转换为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,支持复杂结构和动态类型。推荐

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);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值