DBCHM/MJTop.Data/Ext.Data.cs

556 lines
20 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 数据对象扩展方法类
/// </summary>
public static class ExtData
{
#region DataTable 1
/// <summary>
/// 根据类型的属性集合匹配修改DataTable列名用来处理属性名与列名不一致的大小写问题
/// </summary>
/// <typeparam name="P">对象类型</typeparam>
/// <param name="data">要修改列名的DataTable</param>
//public static void CompareModify<P>(this DataTable data)
//{
// var propNames = TypeInfo<P>.PropNames;
// foreach (string propName in propNames)
// {
// if (data.Columns[propName] != null)
// {
// data.Columns[propName].ColumnName = propName;
// }
// }
//}
/// <summary>
/// DataTable 转实体类型数据
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="dt">数据源</param>
/// <param name="IsCompareModify">是否匹配修改DataTable列名用来处理属性名与列名不一致的大小写问题</param>
/// <returns>对象集合</returns>
//public static List<T> ToList<T>(this DataTable dt, bool IsCompareModify = false) where T : class
//{
// if (dt == null || dt.Rows.Count <= 0)
// {
// return new List<T>();
// }
// if (IsCompareModify)
// {
// CompareModify<T>(dt);
// }
// List<T> list = new List<T>();
// if (dt == null) return list;
// DataTableEntityBuilder<T> eblist = DataTableEntityBuilder<T>.CreateBuilder(dt.Rows[0]);
// foreach (DataRow info in dt.Rows)
// list.Add(eblist.Build(info));
// dt.Dispose();
// dt = null;
// return list;
//}
//internal class DataTableEntityBuilder<T>
//{
// 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<T> CreateBuilder(DataRow dataRow)
// {
// DataTableEntityBuilder<T> dynamicBuilder = new DataTableEntityBuilder<T>();
// 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
/// <summary>
/// 反射 将行数据转换为实体对象
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="row">行数据</param>
/// <returns>实体对象</returns>
public static T ConvertToObjectFromDR<T>(this DataRow row)
{
if (row == null)
{
return default(T);
}
T obj = (T)Activator.CreateInstance(typeof(T));
obj = ConvertToObjectFromDR<T>(row, obj);
return obj;
}
/// <summary>
/// 反射 将行数据转换为实体对象
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="row">行数据</param>
/// <param name="obj">对象</param>
/// <returns></returns>
private static T ConvertToObjectFromDR<T>(this DataRow row, T obj)
{
if (row == null)
{
return default(T);
}
Type type = TypeInfo<T>.TyThis;
System.Reflection.PropertyInfo[] propInfo = TypeInfo<T>.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;
}
/// <summary>
/// 反射将datatable转换为List对象
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="this">datatable数据</param>
/// <returns>List对象</returns>
public static List<T> ConvertToListObject<T>(this DataTable @this)
{
if (@this == null || @this.Rows.Count <= 0)
{
return new List<T>();
}
List<T> objs = new List<T>();
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
/// <summary>
/// DataTable生成实体
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dataTable"></param>
/// <returns></returns>
public static IEnumerable<T> ToListModel<T>(this DataTable dataTable) where T : class, new()
{
return BWofter.Converters.Data.DataTableConverter<T>.ToEntities(dataTable);
}
#endregion
#region DataTable DataRow DataColumn
/// <summary>
/// 改变:将DataTable的其中 某列(默认第一列)数据 存储为 List
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="this">数据源</param>
/// <param name="columnName">列名,默认第一列</param>
/// <returns>List数据</returns>
public static List<T> TransList<T>(this DataTable @this, string columnName = null)
{
List<T> lst = new List<T>();
if (@this == null || @this.Rows.Count < 0)
{
return lst;
}
else
{
foreach (DataRow dr in @this.Rows)
{
if (columnName == null)
{
lst.Add(dr[0].ChangeType<T>());
}
else
{
lst.Add(dr[columnName].ChangeType<T>());
}
}
}
return lst;
}
/// <summary>
/// 将DataTable的其中 两列数据 存储为 Dictionary
/// </summary>
/// <param name="this">数据源</param>
/// <param name="ColumnNameKey">列1(键)</param>
/// <param name="ColumnVal">列2(值)</param>
/// <returns>Dictionary集合</returns>
public static Dictionary<TKey, TVal> TransDict<TKey, TVal>(this DataTable @this, string ColumnNameKey, string ColumnVal)
{
Dictionary<TKey, TVal> dict = new Dictionary<TKey, TVal>();
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;
}
/// <summary>
/// 将DataTable的其中 两列数据 存储为 NameValueCollection
/// </summary>
/// <param name="this">数据源</param>
/// <param name="ColumnNameKey">列1(键)</param>
/// <param name="ColumnVal">列2(值)</param>
/// <returns>NameValueCollection集合</returns>
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;
}
/// <summary>
///给当前DataTable增加列名
/// </summary>
/// <param name="this">DataTable对象</param>
/// <param name="columns">列信息</param>
/// <returns>增加列后的DataTable</returns>
public static DataTable AddColumns(this DataTable @this, params KeyValuePair<string, Type>[] 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;
}
/// <summary>
/// 获取首行数据
/// </summary>
/// <param name="this">DataTable数据</param>
/// <returns>首行数据</returns>
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;
}
/// <summary>
/// 获取最后一行数据
/// </summary>
/// <param name="this">DataTable数据</param>
/// <returns>最后一行数据</returns>
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;
}
/// <summary>
/// 添加列数据
/// </summary>
/// <param name="this">行集合</param>
/// <param name="drs">行数据</param>
public static void AddRange(this DataRowCollection @this, IEnumerable<DataRow> drs)
{
foreach (DataRow dr in drs)
{
@this.Add(dr.ItemArray);
}
}
/// <summary>
/// 获取所有DataColumn
/// </summary>
/// <param name="columnCollection">列集合</param>
/// <returns>列数组</returns>
public static DataColumn[] ToArray(this DataColumnCollection columnCollection)
{
List<DataColumn> lstDC = new List<DataColumn>();
foreach (DataColumn dc in columnCollection)
{
lstDC.Add(dc);
}
return lstDC.ToArray();
}
/// <summary>
/// 将DataRow转为 dynamic 类型对象
/// </summary>
/// <param name="this">行数据</param>
/// <returns></returns>
public static dynamic ToExpandoObject(this DataRow @this)
{
dynamic entity = new ExpandoObject();
var expandoDict = (IDictionary<string, object>)entity;
foreach (DataColumn column in @this.Table.Columns)
{
expandoDict.Add(column.ColumnName, @this[column]);
}
return expandoDict;
}
#endregion
#region DbParameterCollection
/// <summary>
/// DbParameterCollection 转数组
/// </summary>
/// <param name="parameterCollection">DbParameter集合</param>
/// <returns>数组形式的 DbParameter </returns>
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
/// <summary>
/// 获取数据库类型对应的 数据类型/Dbtype的字典
/// </summary>
/// <param name="dbType">数据库类型</param>
/// <returns>数据类型/Dbtype的字典</returns>
public static Dictionary<string, DbType> 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("未知数据库类型!");
}
}
/// <summary>
/// 数据库类型,列 对应的DbType
/// </summary>
/// <param name="dbType"></param>
/// <param name="colInfo"></param>
/// <returns>DbType</returns>
//public static DbType GetDbType(this DBType dbType, ColumnInfo colInfo)
//{
// DbType dType;
// if (dbType.DictDbType().TryGetValue(colInfo.TypeName, out dType))
// {
// return dType;
// }
// return DbType.AnsiString;
//}
/// <summary>
/// 获取当前数据库类型的参数化字符
/// </summary>
/// <param name="dbType">数据库类型</param>
/// <returns>参数化字符</returns>
public static string ParameterChar(this DBType dbType)
{
return Global.ParameterCharMap[dbType];
}
#endregion
/// <summary>
/// 引用类型对象的序列化(深度克隆)
/// 注:使用之前先将对象标记为 [Serializable] 可序列化。
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="RealObject">对象</param>
/// <returns>返回深度克隆后的新对象</returns>
internal static T Clone<T>(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);
}
}
}
}