using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Data.Common;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace MJTop.Data
{
///
/// 数据对象扩展方法类
///
public static class ExtData
{
#region DataTable 转实体类型数据 方法1
///
/// 根据类型的属性集合,匹配修改DataTable列名(用来处理属性名与列名不一致的大小写问题)
///
/// 对象类型
/// 要修改列名的DataTable
//public static void CompareModify
(this DataTable data)
//{
// var propNames = TypeInfo
.PropNames;
// foreach (string propName in propNames)
// {
// if (data.Columns[propName] != null)
// {
// data.Columns[propName].ColumnName = propName;
// }
// }
//}
///
/// DataTable 转实体类型数据
///
/// 实体类型
/// 数据源
/// 是否匹配修改DataTable列名(用来处理属性名与列名不一致的大小写问题)
/// 对象集合
//public static List ToList(this DataTable dt, bool IsCompareModify = false) where T : class
//{
// if (dt == null || dt.Rows.Count <= 0)
// {
// return new List();
// }
// if (IsCompareModify)
// {
// CompareModify(dt);
// }
// List list = new List();
// if (dt == null) return list;
// DataTableEntityBuilder eblist = DataTableEntityBuilder.CreateBuilder(dt.Rows[0]);
// foreach (DataRow info in dt.Rows)
// list.Add(eblist.Build(info));
// dt.Dispose();
// dt = null;
// return list;
//}
//internal class DataTableEntityBuilder
//{
// private static readonly MethodInfo getValueMethod = typeof(DataRow).GetMethod("get_Item", new Type[] { typeof(int) });
// private static readonly MethodInfo isDBNullMethod = typeof(DataRow).GetMethod("IsNull", new Type[] { typeof(int) });
// private delegate T Load(DataRow dataRecord);
// private Load handler;
// private DataTableEntityBuilder() { }
// public T Build(DataRow dataRecord)
// {
// return handler(dataRecord);
// }
// public static DataTableEntityBuilder CreateBuilder(DataRow dataRow)
// {
// DataTableEntityBuilder dynamicBuilder = new DataTableEntityBuilder();
// DynamicMethod method = new DynamicMethod("DynamicCreateEntity", typeof(T), new Type[] { typeof(DataRow) }, typeof(T), true);
// ILGenerator generator = method.GetILGenerator();
// LocalBuilder result = generator.DeclareLocal(typeof(T));
// generator.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));
// generator.Emit(OpCodes.Stloc, result);
// for (int index = 0; index < dataRow.ItemArray.Length; index++)
// {
// PropertyInfo propertyInfo = typeof(T).GetProperty(dataRow.Table.Columns[index].ColumnName);
// Label endIfLabel = generator.DefineLabel();
// if (propertyInfo != null && propertyInfo.GetSetMethod() != null)
// {
// generator.Emit(OpCodes.Ldarg_0);
// generator.Emit(OpCodes.Ldc_I4, index);
// generator.Emit(OpCodes.Callvirt, isDBNullMethod);
// generator.Emit(OpCodes.Brtrue, endIfLabel);
// generator.Emit(OpCodes.Ldloc, result);
// generator.Emit(OpCodes.Ldarg_0);
// generator.Emit(OpCodes.Ldc_I4, index);
// generator.Emit(OpCodes.Callvirt, getValueMethod);
// generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
// generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());
// generator.MarkLabel(endIfLabel);
// }
// }
// generator.Emit(OpCodes.Ldloc, result);
// generator.Emit(OpCodes.Ret);
// dynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load));
// return dynamicBuilder;
// }
//}
#endregion
#region DataTable 转实体类型数据 方法2
///
/// 反射 将行数据转换为实体对象
///
/// 实体类型
/// 行数据
/// 实体对象
public static T ConvertToObjectFromDR(this DataRow row)
{
if (row == null)
{
return default(T);
}
T obj = (T)Activator.CreateInstance(typeof(T));
obj = ConvertToObjectFromDR(row, obj);
return obj;
}
///
/// 反射 将行数据转换为实体对象
///
/// 实体类型
/// 行数据
/// 对象
///
private static T ConvertToObjectFromDR(this DataRow row, T obj)
{
if (row == null)
{
return default(T);
}
Type type = TypeInfo.TyThis;
System.Reflection.PropertyInfo[] propInfo = TypeInfo.Props;
for (int i = 0; i < propInfo.Length; i++)
{
if (row.Table.Columns[propInfo[i].Name] != null && row[propInfo[i].Name] != System.DBNull.Value && propInfo[i].CanWrite)
{
object objVal = row[propInfo[i].Name];
Type typeVal = Nullable.GetUnderlyingType(propInfo[i].PropertyType) ?? propInfo[i].PropertyType;
int mark = 0;
try
{
if (typeVal.Name == "Guid")
{
mark = 1;
propInfo[i].SetValue(obj, Guid.Parse(objVal.ToString()), null);
}
else
{
if (typeVal.IsEnum && objVal != null)
{
Type tyEnum = Enum.GetUnderlyingType(typeVal);
if (tyEnum.IsAssignableFrom(typeof(int)))
{
mark = 2;
propInfo[i].SetValue(obj, Enum.Parse(typeVal, objVal.ToString()), null);
}
else
{
mark = 3;
propInfo[i].SetValue(obj, Convert.ChangeType(objVal, typeVal), null);
}
}
else
{
if (objVal == null || string.IsNullOrWhiteSpace(objVal.ToString()))
{
mark = 4;
if (propInfo[i].PropertyType.IsNullableType())
{
objVal = null;
}
propInfo[i].SetValue(obj, objVal, null);
}
else
{
mark = 5;
propInfo[i].SetValue(obj, Convert.ChangeType(objVal, typeVal), null);
}
}
}
}
catch (Exception ex)
{
throw new ArgumentException("SetValue出错!(" + mark + ")", propInfo[i].Name + ":" + objVal, ex);
}
}
}
return obj;
}
///
/// 反射将datatable转换为List对象
///
/// 实体类型
/// datatable数据
/// List对象
public static List ConvertToListObject(this DataTable @this)
{
if (@this == null || @this.Rows.Count <= 0)
{
return new List();
}
List objs = new List();
for (int i = 0; i < @this.Rows.Count; i++)
{
T obj = (T)Activator.CreateInstance(typeof(T));
obj = ConvertToObjectFromDR(@this.Rows[i], obj);
objs.Add(obj);
}
return objs;
}
#endregion
#region DataTable 转实体类型数据 方法3
///
/// DataTable生成实体
///
///
///
///
public static IEnumerable ToListModel(this DataTable dataTable) where T : class, new()
{
return BWofter.Converters.Data.DataTableConverter.ToEntities(dataTable);
}
#endregion
#region DataTable DataRow DataColumn 扩展
///
/// 改变:将DataTable的其中 某列(默认第一列)数据 存储为 List
///
/// 数据类型
/// 数据源
/// 列名,默认第一列
/// List数据
public static List TransList(this DataTable @this, string columnName = null)
{
List lst = new List();
if (@this == null || @this.Rows.Count < 0)
{
return lst;
}
else
{
foreach (DataRow dr in @this.Rows)
{
if (columnName == null)
{
lst.Add(dr[0].ChangeType());
}
else
{
lst.Add(dr[columnName].ChangeType());
}
}
}
return lst;
}
///
/// 将DataTable的其中 两列数据 存储为 Dictionary
///
/// 数据源
/// 列1(键)
/// 列2(值)
/// Dictionary集合
public static Dictionary TransDict(this DataTable @this, string ColumnNameKey, string ColumnVal)
{
Dictionary dict = new Dictionary();
if (@this == null || @this.Rows.Count <= 0)
{
return dict;
}
else
{
foreach (DataRow dr in @this.Rows)
{
TKey k = (TKey)dr[ColumnNameKey].ChangeType(typeof(TKey));
TVal v = (TVal)dr[ColumnVal].ChangeType(typeof(TVal));
dict.Add(k, v);
}
}
return dict;
}
///
/// 将DataTable的其中 两列数据 存储为 NameValueCollection
///
/// 数据源
/// 列1(键)
/// 列2(值)
/// NameValueCollection集合
public static NameValueCollection MapperNameValues(this DataTable @this, string ColumnNameKey, string ColumnVal)
{
NameValueCollection nvc = new NameValueCollection();
if (@this == null || @this.Rows.Count <= 0)
{
return nvc;
}
else
{
foreach (DataRow dr in @this.Rows)
{
nvc.Add(dr[ColumnNameKey].ToString(), dr[ColumnVal].ToString());
}
}
return nvc;
}
///
///给当前DataTable增加列名
///
/// DataTable对象
/// 列信息
/// 增加列后的DataTable
public static DataTable AddColumns(this DataTable @this, params KeyValuePair[] columns)
{
if (@this == null)
{
@this = new DataTable();
}
if (columns != null && columns.Length > 0)
{
foreach (var col in columns)
{
@this.Columns.Add(new DataColumn(col.Key, col.Value));
}
}
return @this;
}
///
/// 获取首行数据
///
/// DataTable数据
/// 首行数据
public static DataRow FirstRow(this DataTable @this)
{
if (@this == null)
{
throw new ArgumentNullException("DataTable不能为null");
}
if (@this.Rows.Count > 0)
{
return @this.Rows[0];
}
return null;
}
///
/// 获取最后一行数据
///
/// DataTable数据
/// 最后一行数据
public static DataRow LastRow(this DataTable @this)
{
if (@this == null)
{
throw new ArgumentNullException("DataTable不能为null");
}
if (@this.Rows.Count > 0)
{
return @this.Rows[@this.Rows.Count - 1];
}
return null;
}
///
/// 添加列数据
///
/// 行集合
/// 行数据
public static void AddRange(this DataRowCollection @this, IEnumerable drs)
{
foreach (DataRow dr in drs)
{
@this.Add(dr.ItemArray);
}
}
///
/// 获取所有DataColumn
///
/// 列集合
/// 列数组
public static DataColumn[] ToArray(this DataColumnCollection columnCollection)
{
List lstDC = new List();
foreach (DataColumn dc in columnCollection)
{
lstDC.Add(dc);
}
return lstDC.ToArray();
}
///
/// 将DataRow转为 dynamic 类型对象
///
/// 行数据
///
public static dynamic ToExpandoObject(this DataRow @this)
{
dynamic entity = new ExpandoObject();
var expandoDict = (IDictionary)entity;
foreach (DataColumn column in @this.Table.Columns)
{
expandoDict.Add(column.ColumnName, @this[column]);
}
return expandoDict;
}
#endregion
#region DbParameterCollection 扩展
///
/// DbParameterCollection 转数组
///
/// DbParameter集合
/// 数组形式的 DbParameter
public static DbParameter[] ToArray(this DbParameterCollection parameterCollection)
{
if (parameterCollection == null || parameterCollection.Count <= 0)
{
return null;
}
DbParameter[] paras = new DbParameter[parameterCollection.Count];
for (int j = 0; j < parameterCollection.Count; j++)
{
paras[j] = parameterCollection[j];
}
return paras;
}
#endregion
#region DBType 扩展
///
/// 获取数据库类型对应的 数据类型/Dbtype的字典
///
/// 数据库类型
/// 数据类型/Dbtype的字典
public static Dictionary DictDbType(this DBType dbType)
{
switch (dbType)
{
case DBType.SqlServer:
return Global.Dict_SqlServer_DbType;
case DBType.MySql:
return Global.Dict_MySql_DbType;
case DBType.Oracle:
return Global.Dict_Oracle_DbType;
case DBType.OracleDDTek:
return Global.Dict_Oracle_DbType;
case DBType.PostgreSql:
return Global.Dict_PostgreSql_DbType;
case DBType.SQLite:
return Global.Dict_Sqlite_DbType;
default:
throw new ArgumentException("未知数据库类型!");
}
}
///
/// 数据库类型,列 对应的DbType
///
///
///
/// DbType
//public static DbType GetDbType(this DBType dbType, ColumnInfo colInfo)
//{
// DbType dType;
// if (dbType.DictDbType().TryGetValue(colInfo.TypeName, out dType))
// {
// return dType;
// }
// return DbType.AnsiString;
//}
///
/// 获取当前数据库类型的参数化字符
///
/// 数据库类型
/// 参数化字符
public static string ParameterChar(this DBType dbType)
{
return Global.ParameterCharMap[dbType];
}
#endregion
///
/// 引用类型对象的序列化(深度克隆)
/// 注:使用之前先将对象标记为 [Serializable] 可序列化。
///
/// 对象类型
/// 对象
/// 返回深度克隆后的新对象
internal static T Clone(this T RealObject)
{
if (RealObject == null)
{
return default(T);
}
using (Stream objectStream = new MemoryStream())
{
//利用 System.Runtime.Serialization序列化与反序列化完成引用对象的复制
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(objectStream, RealObject);
objectStream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(objectStream);
}
}
}
}