using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;

namespace WaterCloud.Code
{
	public static class DataTableHelper
	{
		public static DataTable ListToDataTable<T>(List<T> entitys)
		{
			//检查实体集合不能为空
			if (entitys == null || entitys.Count < 1)
			{
				throw new Exception("需转换的集合为空");
			}
			//取出第一个实体的所有Propertie
			Type entityType = entitys[0].GetType();
			PropertyInfo[] entityProperties = entityType.GetProperties();

			//生成DataTable的structure
			//生产代码中，应将生成的DataTable结构Cache起来，此处略
			DataTable dt = new DataTable();
			for (int i = 0; i < entityProperties.Length; i++)
			{
				dt.Columns.Add(entityProperties[i].Name);
			}
			//将所有entity添加到DataTable中
			foreach (object entity in entitys)
			{
				//检查所有的的实体都为同一类型
				if (entity.GetType() != entityType)
				{
					throw new Exception("要转换的集合元素类型不一致");
				}
				object[] entityValues = new object[entityProperties.Length];
				for (int i = 0; i < entityProperties.Length; i++)
				{
					entityValues[i] = entityProperties[i].GetValue(entity, null);
				}
				dt.Rows.Add(entityValues);
			}
			return dt;
		}

		/// <summary>
		/// List过滤
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="entitys"></param>
		/// <param name="list"></param>
		/// <returns></returns>
		public static List<T> ListFilter<T>(List<T> entitys, List<string> list)
		{
			//检查实体集合不能为空
			if (entitys == null || entitys.Count < 1)
			{
				throw new Exception("需转换的集合为空");
			}
			//取出第一个实体的所有Propertie
			Type entityType = entitys[0].GetType();
			PropertyInfo[] entityProperties = entityType.GetProperties();

			//将所有entity过滤
			foreach (object entity in entitys)
			{
				//检查所有的的实体都为同一类型
				if (entity.GetType() != entityType)
				{
					throw new Exception("要转换的集合元素类型不一致");
				}
				for (int i = 0; i < entityProperties.Length; i++)
				{
					if (!list.Contains(entityProperties[i].Name))
					{
						entityProperties[i].SetValue(entity, null);
					}
				}
			}
			return entitys;
		}

		/// <summary>
		/// DataTable转成List
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="dt"></param>
		/// <returns></returns>
		public static List<T> ToDataList<T>(this DataTable dt)
		{
			var list = new List<T>();
			var plist = new List<PropertyInfo>(typeof(T).GetProperties());
			foreach (DataRow item in dt.Rows)
			{
				T s = Activator.CreateInstance<T>();
				for (int i = 0; i < dt.Columns.Count; i++)
				{
					PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName);
					if (info != null)
					{
						try
						{
							if (!Convert.IsDBNull(item[i]))
							{
								object v = null;
								if (info.PropertyType.ToString().Contains("System.Nullable"))
								{
									v = Convert.ChangeType(item[i], Nullable.GetUnderlyingType(info.PropertyType));
								}
								else
								{
									v = Convert.ChangeType(item[i], info.PropertyType);
								}
								info.SetValue(s, v, null);
							}
						}
						catch (Exception ex)
						{
							throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message);
						}
					}
				}
				list.Add(s);
			}
			return list;
		}
	}
}