自用 .net C# List集合和DataTable互转,可自定义表头

发布时间 2023-04-13 08:52:56作者: 你好创造者
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;

namespace AddrList.Common
{
    public static class DataTable2ListHelper
    {
        /// <summary>
        /// DataTable转List
        /// </summary>
        /// <typeparam name="T">列表项类型</typeparam>
        /// <param name="dt">要转换的内存表</param>
        /// <returns></returns>
        public static List<T> DatatTable2List<T>(this DataTable dt) where T : class, new()
        {
            var list = new List<T>();
            var ps = typeof(T).GetProperties();

            //遍历所有DataTable的行
            foreach (DataRow dr in dt.Rows)
            {
                var t = new T();
                //通过反射获取T类型的所有成员
                foreach (PropertyInfo pi in ps)
                {
                    if (dt.Columns.Contains(pi.Name) && dr[pi.Name] != DBNull.Value)
                    {
                        object value = Convert.ChangeType(dr[pi.Name], pi.PropertyType);
                        //给T类型字段赋值
                        pi.SetValue(t, value, null);
                    }
                }
                //将T类型添加到集合list
                list.Add(t);
            }
            return list;
        }

        /// <summary>
        /// List转换为DataTable
        /// </summary>
        /// <typeparam name="T">列表项类型</typeparam>
        /// <param name="list">要转换的集合</param>
        /// <returns></returns>
        public static DataTable List2DataTable<T>(this List<T> list) where T : class
        {
            var dt = new DataTable();
            var ps = typeof(T).GetProperties();

            var columns = ps.Select(p => new DataColumn(p.Name, p.PropertyType)).ToArray();
            dt.Columns.AddRange(columns);

            foreach (T t in list)
            {
                DataRow dr = dt.NewRow();
                foreach (PropertyInfo pi in ps)
                {
                    if (dt.Columns.Contains(pi.Name) && pi.GetValue(t) != null)
                    {
                        dr[pi.Name] = pi.GetValue(t);
                    }
                }
                dt.Rows.Add(dr);
            }

            return dt;
        }

        /// <summary>
        /// DataTable转List
        /// </summary>
        /// <typeparam name="T">列表项类型</typeparam>
        /// <param name="dt">要转换的内存表</param>
        /// <param name="header">表头</param>
        /// <returns></returns>
        public static List<T> DatatTable2List<T>(this DataTable dt, Dictionary<string, string> header) where T : class, new()
        {
            if (!(header?.Any() ?? false)) return DatatTable2List<T>(dt);

            var list = new List<T>();
            var ps = typeof(T).GetProperties();

            foreach (DataColumn column in dt.Columns)
            {
                if (header.Where(m => m.Value == column.ColumnName).Any())
                {
                    column.ColumnName = header.Where(m => m.Value == column.ColumnName).FirstOrDefault().Key;
                }
            }

            //遍历所有DataTable的行
            foreach (DataRow dr in dt.Rows)
            {
                var t = new T();
                //通过反射获取T类型的所有成员
                foreach (PropertyInfo pi in ps)
                {
                    if (dt.Columns.Contains(pi.Name) && dr[pi.Name] != DBNull.Value)
                    {
                        object value = Convert.ChangeType(dr[pi.Name], pi.PropertyType);
                        //给T类型字段赋值
                        pi.SetValue(t, value, null);
                    }
                }
                //将T类型添加到集合list
                list.Add(t);
            }
            return list;
        }

        /// <summary>
        /// List转换为DataTable
        /// </summary>
        /// <typeparam name="T">列表项类型</typeparam>
        /// <param name="list">要转换的集合</param>
        /// <param name="header">表头</param>
        /// <returns></returns>
        public static DataTable List2DataTable<T>(this List<T> list, Dictionary<string, string> header) where T : class
        {
            if (!(header?.Any() ?? false)) return List2DataTable(list);

            var dt = new DataTable();
            var ps = typeof(T).GetProperties();

            dt.Columns.AddRange(
                header.
                Select(m => new DataColumn(m.Value, ps.Where(p => p.Name == m.Key).FirstOrDefault().PropertyType)).
                ToArray());

            foreach (T t in list)
            {
                DataRow dr = dt.NewRow();
                foreach (PropertyInfo pi in ps)
                {
                    if (header.ContainsKey(pi.Name) &&
                        dt.Columns.Contains(header[pi.Name]) &&
                        pi.GetValue(t) != null)
                    {
                        dr[header[pi.Name]] = pi.GetValue(t);
                    }
                }
                dt.Rows.Add(dr);
            }

            return dt;
        }

        /// <summary>
        /// 更换内存表表头
        /// </summary>
        /// <param name="dt">内存表</param>
        /// <param name="header">表头</param>
        /// <returns></returns>
        public static DataTable ChangeHeader(this DataTable dt, Dictionary<string, string> header)
        {
            var l = dt.Columns.Count;

            for (int i = 0; i < l; i++)
            {
                DataColumn column = dt.Columns[i];
                if (header.ContainsKey(column.ColumnName))
                {
                    column.ColumnName = header[column.ColumnName];
                }
                else
                {
                    dt.Columns.Remove(column);
                }
            }

            return dt;
        }
    }
}