using System;
using System.Collections.Generic;
using System.Data;
using System.Dynamic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace BPA.SAAS.Manage.Comm.Util
{
    public static class DataTableUitity
    {

        /// <summary>
        /// 将DataTable 转换成 List<dynamic>
        /// reverse 反转：控制返回结果中是只存在 FilterField 指定的字段,还是排除.
        /// [flase 返回FilterField 指定的字段]|[true 返回结果剔除 FilterField 指定的字段]
        /// FilterField  字段过滤，FilterField 为空 忽略 reverse 参数；返回DataTable中的全部数
        /// </summary>
        /// <param name="table">DataTable</param>
        /// <param name="reverse">
        /// 反转：控制返回结果中是只存在 FilterField 指定的字段,还是排除.
        /// [flase 返回FilterField 指定的字段]|[true 返回结果剔除 FilterField 指定的字段]
        ///</param>
        /// <param name="FilterField">字段过滤，FilterField 为空 忽略 reverse 参数；返回DataTable中的全部数据</param>
        /// <returns>List<dynamic></returns>
        public static List<dynamic> ToDynamicList(this DataTable table, bool reverse = true, params string[] FilterField)
        {
            var modelList = new List<dynamic>();
            foreach (DataRow row in table.Rows)
            {
                dynamic model = new ExpandoObject();
                var dict = (IDictionary<string, object>)model;
                foreach (DataColumn column in table.Columns)
                {
                    if (FilterField.Length != 0)
                    {
                        if (reverse == true)
                        {
                            if (!FilterField.Contains(column.ColumnName))
                            {
                                dict[column.ColumnName] = row[column];
                            }
                        }
                        else
                        {
                            if (FilterField.Contains(column.ColumnName))
                            {
                                dict[column.ColumnName] = row[column];
                            }
                        }
                    }
                    else
                    {
                        dict[column.ColumnName] = row[column];
                    }
                }
                modelList.Add(model);
            }
            return modelList;
        }

        public static List<T> DatatTableToList<T>(DataTable dt) where T : class, new()
        {
            List<T> list = new List<T>();
            T t = new T();
            PropertyInfo[] prop = t.GetType().GetProperties();
            //遍历所有DataTable的行
            foreach (DataRow dr in dt.Rows)
            {
                t = new T();
                //通过反射获取T类型的所有成员
                foreach (PropertyInfo pi in prop)
                {
                    //DataTable列名=属性名
                    if (dt.Columns.Contains(pi.Name))
                    {
                        //属性值不为空
                        if (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;

        }
        public static T ConvertToEntity<T>(DataTable dt) where T : new()
        {
            //定义一个变量，用来接收属性名
            string tempType = string.Empty;
            T t = new T();
            //获得T的所有属性
            PropertyInfo[] propertyInfos = t.GetType().GetProperties();
            foreach (DataRow dr in dt.Rows)
            {
                foreach (PropertyInfo pi in propertyInfos)
                {
                    //将属性名赋值给临时变量
                    tempType = pi.Name;
                    //如果表的列名不包含此属性，则跳过检查下一条属性
                    if (!dt.Columns.Contains(tempType)) continue;
                    //如果此属性可写
                    if (pi.CanWrite)
                    {
                        object value = dr[tempType];
                        //如果表中的字段值不为空，则赋值
                        if (value != DBNull.Value)
                        {
                            value = Convert.ChangeType(value, pi.PropertyType);
                            pi.SetValue(t, value, null);
                        }
                    }
                }
            }
            return t;
        }
        /// <summary>
        /// List转换为DataTable
        /// </summary>
        /// <typeparam name="T">List中的类型</typeparam>
        /// <param name="list">要转换的list</param>
        /// <returns></returns>
        public static DataTable ListToDataTable<T>(List<T> list) where T : class
        {
            DataTable dt = new DataTable();
            PropertyInfo[] prop = typeof(T).GetProperties();
            DataColumn[] ColumnArr = prop.Select(p => new DataColumn(p.Name, p.PropertyType)).ToArray();
            dt.Columns.AddRange(ColumnArr);
            foreach (T t in list)
            {
                DataRow dr = dt.NewRow();
                foreach (PropertyInfo pi in prop)
                {
                    if (dt.Columns.Contains(pi.Name))
                    {
                        if (pi.GetValue(t) != null)
                        {
                            dr[pi.Name] = pi.GetValue(t);
                        }
                    }
                }
                dt.Rows.Add(dr);
            }

            return dt;
        }
    }
}
