DeviceManager/DeviceRepair.Utils/DTOHelper.cs

705 lines
28 KiB
C#
Raw Permalink Normal View History

2024-07-27 01:44:19 +00:00
using DeviceRepair.Models.Attr;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Reflection;
namespace DeviceRepair.Utils
{
/// <summary>
/// 实体对象<->数据集转换帮助类
/// </summary>
public static class DTOHelper<TData> where TData : class, new()
{
#region Methods
#region ->DataSet数据集
private static void AddColumnsByDTOProperty(PropertyInfo pi, ref DataTable dtResult)
{
if (dtResult == null)
{
dtResult = new DataTable();
}
if (dtResult.Columns.Contains(pi.Name))
{
return;
}
Type colType = pi.PropertyType;
#region Myl20190801
object[] objBoolConverter = pi.GetCustomAttributes(typeof(BoolConverterAttribute), true);
if (objBoolConverter != null && objBoolConverter.Length > 0)
{
colType = ((BoolConverterAttribute)objBoolConverter[0]).ConvertType;
}
#endregion
if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
{
if (colType.GetGenericArguments()[0].IsEnum)
{
//V1.0.1
colType = typeof(string);
//V1.0.1
}
else
{
colType = colType.GetGenericArguments()[0];
}
}
else if (colType.IsEnum)
{
colType = typeof(string);
}
dtResult.Columns.Add(new DataColumn(pi.Name, colType));
}
public static DataSet ConvertDTOToDataSet<T>(IList<T> sourceList, params string[] propertyNameArray) where T : class
{
if (sourceList == null || sourceList.Count == 0)
{
return null;
}
List<string> propertyNameList = new List<string>();
if (propertyNameArray != null)
{
propertyNameList.AddRange(propertyNameArray);
}
DataSet dsResult = new DataSet("Datas");
DataTable dtResult = new DataTable();
Type[] typeArr = sourceList.GetType().GetGenericArguments();
if (typeArr.Length == 0)
{
return dsResult;
}
#region DomIgnore特性的属性 Myl20180206
PropertyInfo[] domProperties = typeArr[0].GetProperties();
IEnumerable<PropertyInfo> domDomNotIngoredPropertyList =
domProperties.Where<System.Reflection.PropertyInfo>((A) =>
{
return A.GetCustomAttributes(typeof(DomFieldIgnoreAttribute), true).Length == 0;
});
#endregion
dtResult.TableName = typeArr[0].Name;
foreach (PropertyInfo pi in domDomNotIngoredPropertyList)
{
if (propertyNameList.Count == 0)
{
//dtResult.Columns.Add(pi.Name, pi.PropertyType);
AddColumnsByDTOProperty(pi, ref dtResult);
}
else
{
if (propertyNameList.Contains(pi.Name))
{
AddColumnsByDTOProperty(pi, ref dtResult);
}
}
}
for (int i = 0; i < sourceList.Count; i++)
{
ArrayList tempList = new ArrayList();
foreach (PropertyInfo pi in domDomNotIngoredPropertyList)
{
#region Bool类型转换 Myl190801
object[] objBoolConverter = pi.GetCustomAttributes(typeof(BoolConverterAttribute), true);
Type boolConvertType = null;
if (objBoolConverter != null && objBoolConverter.Length > 0)
{
boolConvertType = ((BoolConverterAttribute)objBoolConverter[0]).ConvertType;
}
#endregion
if (propertyNameList.Count == 0)
{
object obj = pi.GetValue(sourceList[i], null);
//V1.0.1
if (pi.PropertyType.IsEnum)
{
if (obj != null)
{
obj = ((int)Enum.Parse(pi.PropertyType, obj.ToString())).ToString();
}
}
//V1.0.1
#region Bool类型转换 Myl190801
if (pi.PropertyType == typeof(bool))
{
if (boolConvertType != null)
{
if (obj != null)
{
obj = Convert.ChangeType(bool.Parse(obj.ToString()) ? ((BoolConverterAttribute)objBoolConverter[0]).BoolString[0] : ((BoolConverterAttribute)objBoolConverter[0]).BoolString[1], boolConvertType);
}
}
}
#endregion
tempList.Add(obj);
}
else
{
if (propertyNameList.Contains(pi.Name))
{
object obj = pi.GetValue(sourceList[i], null);
//V1.0.1
if (pi.PropertyType.IsEnum)
{
if (obj != null)
{
obj = ((int)Enum.Parse(pi.PropertyType, obj.ToString())).ToString();
}
}
else
{
//V1.0.3
if ((pi.PropertyType.IsGenericType) && (pi.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)))
{
if (pi.PropertyType.GetGenericArguments()[0].IsEnum)
{
if (obj != null)
{
obj = ((int)Enum.Parse(pi.PropertyType.GetGenericArguments()[0], obj.ToString())).ToString();
}
}
}
//V1.0.3
}
//V1.0.1
#region Bool类型转换 Myl190801
if (pi.PropertyType == typeof(bool))
{
if (boolConvertType != null)
{
if (obj != null)
{
obj = Convert.ChangeType(bool.Parse(obj.ToString()) ? ((BoolConverterAttribute)objBoolConverter[0]).BoolString[0] : ((BoolConverterAttribute)objBoolConverter[0]).BoolString[1], boolConvertType);
}
}
}
#endregion
tempList.Add(obj);
}
}
}
object[] array = tempList.ToArray();
dtResult.LoadDataRow(array, true);
}
dsResult.Tables.Add(dtResult);
return dsResult;
}
public static DataSet ConvertDTOToDataSet(IList<TData> sourceList, params string[] propertyNameArray)
{
return ConvertDTOToDataSet<TData>(sourceList, propertyNameArray);
}
public static DataSet ConvertSingleDTOToDataSet(TData sourceData, params string[] propertyNameArray)
{
return ConvertDTOToDataSet(new List<TData>() { sourceData }, propertyNameArray);
}
#endregion
#region DataTable数据集->
#region DataTable利用泛型填充实体类
/// <summary>
/// DataTable利用泛型填充实体类
/// </summary>
/// <typeparam name="U">实体类类型</typeparam>
/// <param name="dtData">待填充的DataTable</param>
/// <returns>
/// 返回填充完的实体类对象集合
/// </returns>
public static IList<U> DataTableToList<U>(DataTable dtData) where U : class
{
IList<U> listObject = new List<U>();
U t = default(U);
PropertyInfo[] propertypes = null;
string tempColumnName = string.Empty;
foreach (DataRow eachRow in dtData.Rows)
{
t = Activator.CreateInstance<U>();
propertypes = t.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
foreach (PropertyInfo eachProperty in propertypes)
{
if (!eachProperty.CanWrite)
{
//Myl - 20190122
continue;
}
#region Myl - 20190122
tempColumnName = eachProperty.Name;
if (dtData.Columns.Contains(tempColumnName))
{
#region Myl - 20190128
int? iDigits = null;
object[] objNumberDigits = eachProperty.GetCustomAttributes(typeof(NumberDigitsAttribute), true);
if (objNumberDigits != null && objNumberDigits.Length > 0)
{
iDigits = ((NumberDigitsAttribute)objNumberDigits[0]).Digits;
}
#endregion
object value = Convert.IsDBNull(eachRow[tempColumnName]) ? null : iDigits == null ? eachRow[tempColumnName] : Math.Round(decimal.Parse(eachRow[tempColumnName].ToString()), iDigits.Value);
if (value != null)
{
if (!eachProperty.PropertyType.IsGenericType)
{
//非泛型
if (eachProperty.PropertyType.IsEnum)
{
//赋值枚举 20210304 Myl Add
eachProperty.SetValue(t, string.IsNullOrEmpty(value.ToString().Trim()) ? null : Enum.Parse(eachProperty.PropertyType, value.ToString().Trim()), null);
}
else if (eachProperty.PropertyType == typeof(string))
{
eachProperty.SetValue(t, string.IsNullOrEmpty(value.ToString().Trim()) ? null : Convert.ChangeType(value.ToString().Trim(), eachProperty.PropertyType, null), null);
}
else
{
eachProperty.SetValue(t, string.IsNullOrEmpty(value.ToString().Trim()) ? null : Convert.ChangeType(value, eachProperty.PropertyType, null), null);
}
}
else
{
//泛型Nullable<>
Type genericTypeDefinition = eachProperty.PropertyType.GetGenericTypeDefinition();
if (genericTypeDefinition == typeof(Nullable<>))
{
if (eachProperty.PropertyType.GetGenericArguments().Count() > 0 && eachProperty.PropertyType.GetGenericArguments()[0].IsEnum)
{
//赋值枚举 20210304 Myl Add
eachProperty.SetValue(t, string.IsNullOrEmpty(value.ToString().Trim()) ? null : Enum.Parse(eachProperty.PropertyType.GetGenericArguments()[0], value.ToString().Trim()), null);
}
else
{
eachProperty.SetValue(t, string.IsNullOrEmpty(value.ToString().Trim()) ? null : Convert.ChangeType(value, Nullable.GetUnderlyingType(eachProperty.PropertyType), null), null);
}
}
}
}
}
#endregion
}
listObject.Add(t);
}
return listObject;
}
#region DataTable利用泛型填充实体类
/// <summary>
/// DataTable利用泛型填充实体类
/// </summary>
/// <param name="dtData">待填充的DataTable</param>
/// <returns></returns>
public static IList<TData> DataTableToList(DataTable dtData)
{
return DataTableToList<TData>(dtData);
}
/// <summary>
/// DataTable利用泛型填充实体类并制定特定的筛选条件
/// Myl 20210310
/// </summary>
/// <param name="dtData">待填充的DataTable</param>
/// <param name="filterString">筛选条件</param>
/// <returns></returns>
public static IList<TData> DataTableToList(DataTable dtData, string filterString)
{
if (!string.IsNullOrEmpty(filterString))
{
DataTable dtFilter = dtData.Clone();
var vFilterRows = dtData.Select(filterExpression: filterString);
foreach (var eachFilterRow in vFilterRows)
{
DataRow drFilterNewRow = dtFilter.NewRow();
drFilterNewRow.ItemArray = eachFilterRow.ItemArray;
dtFilter.Rows.Add(drFilterNewRow);
}
return DataTableToList(dtFilter);
}
else
{
return DataTableToList(dtData);
}
}
#endregion
#endregion
public static TData ToEntity(DataRow adaptedRow)
{
if (adaptedRow == null)
{
return default(TData);
}
TData entity = Activator.CreateInstance<TData>();
CopyToEntity(entity, adaptedRow);
return entity;
}
public static object ToEntity(DataRow adaptedRow, Type entityType)
{
if (entityType == null || adaptedRow == null)
{
return null;
}
object entity = Activator.CreateInstance(entityType);
CopyToEntity(entity, adaptedRow);
return entity;
}
public static T ToEntity<T>(DataRow adaptedRow, T value) where T : new()
{
T item = new T();
if (value == null || adaptedRow == null)
{
return item;
}
item = Activator.CreateInstance<T>();
CopyToEntity(item, adaptedRow);
return item;
}
public static TData ToEntity(DataRow adaptedRow, TData value)
{
return ToEntity<TData>(adaptedRow, value);
}
public static void CopyToEntity(object entity, DataRow adaptedRow)
{
if (entity == null || adaptedRow == null)
{
return;
}
PropertyInfo[] propertyInfos = entity.GetType().GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
if (!CanSetPropertyValue(propertyInfo, adaptedRow))
{
continue;
}
try
{
if (adaptedRow[propertyInfo.Name] is DBNull)
{
propertyInfo.SetValue(entity, null, null);
continue;
}
SetPropertyValue(entity, adaptedRow, propertyInfo);
}
finally
{
}
}
}
private static bool CanSetPropertyValue(PropertyInfo propertyInfo, DataRow adaptedRow)
{
if (!propertyInfo.CanWrite)
{
return false;
}
if (!adaptedRow.Table.Columns.Contains(propertyInfo.Name))
{
return false;
}
return true;
}
private static void SetPropertyValue(object entity, DataRow adaptedRow, PropertyInfo propertyInfo)
{
if (propertyInfo.PropertyType == typeof(DateTime?) ||
propertyInfo.PropertyType == typeof(DateTime))
{
DateTime date = DateTime.MaxValue;
DateTime.TryParse(adaptedRow[propertyInfo.Name].ToString(),
CultureInfo.CurrentCulture, DateTimeStyles.None, out date);
propertyInfo.SetValue(entity, date, null);
}
else
{
if (!Convert.IsDBNull(adaptedRow[propertyInfo.Name]))
{
#region Myl20210514
if (!propertyInfo.PropertyType.IsGenericType)
{
//非泛型
if (propertyInfo.PropertyType.IsEnum)
{
//赋值枚举 20210304 Myl Add
propertyInfo.SetValue(entity, string.IsNullOrEmpty(adaptedRow[propertyInfo.Name].ToString().Trim()) ? null : Enum.Parse(propertyInfo.PropertyType, adaptedRow[propertyInfo.Name].ToString().Trim()), null);
}
else if (propertyInfo.PropertyType == typeof(string))
{
propertyInfo.SetValue(entity, string.IsNullOrEmpty(adaptedRow[propertyInfo.Name].ToString().Trim()) ? null : Convert.ChangeType(adaptedRow[propertyInfo.Name].ToString().Trim(), propertyInfo.PropertyType, null), null);
}
else
{
propertyInfo.SetValue(entity, string.IsNullOrEmpty(adaptedRow[propertyInfo.Name].ToString().Trim()) ? null : Convert.ChangeType(adaptedRow[propertyInfo.Name], propertyInfo.PropertyType, null), null);
}
}
else
{
//泛型Nullable<>
Type genericTypeDefinition = propertyInfo.PropertyType.GetGenericTypeDefinition();
if (genericTypeDefinition == typeof(Nullable<>))
{
if (propertyInfo.PropertyType.GetGenericArguments().Count() > 0 && propertyInfo.PropertyType.GetGenericArguments()[0].IsEnum)
{
//赋值枚举 20210304 Myl Add
propertyInfo.SetValue(entity, string.IsNullOrEmpty(adaptedRow[propertyInfo.Name].ToString().Trim()) ? null : Enum.Parse(propertyInfo.PropertyType.GetGenericArguments()[0], adaptedRow[propertyInfo.Name].ToString().Trim()), null);
}
else
{
propertyInfo.SetValue(entity, string.IsNullOrEmpty(adaptedRow[propertyInfo.Name].ToString().Trim()) ? null : Convert.ChangeType(adaptedRow[propertyInfo.Name], Nullable.GetUnderlyingType(propertyInfo.PropertyType), null), null);
}
}
}
#endregion
}
}
}
#endregion
#region V4.0 20230327
/// <summary>
/// DTO按照映射配置特性自动转换为DataSet数据集
/// </summary>
/// <typeparam name="T">泛型类型</typeparam>
/// <param name="sourceList">数据源集合</param>
/// <returns></returns>
public static DataSet DTOToDataSetAutoConvertByAttribute<T>(IList<T> sourceList) where T : class
{
if (sourceList == null || sourceList.Count == 0)
{
return null;
}
DataSet dsResult = new DataSet("Datas");
DataTable dtResult = new DataTable();
Type[] typeArr = sourceList.GetType().GetGenericArguments();
if (typeArr.Length == 0)
{
return dsResult;
}
#region DomIgnore特性的属性 Myl20180206
#region DOM字段的属性 20230327
PropertyInfo[] domProperties = typeArr[0].GetProperties();
IEnumerable<PropertyInfo> domDomNotIngoredPropertyList =
domProperties.Where<System.Reflection.PropertyInfo>((A) =>
{
return A.GetCustomAttributes(typeof(DomFieldMapAttribute), true).Length > 0;
});
if (domDomNotIngoredPropertyList == null || domDomNotIngoredPropertyList.Count() == 0)
{
throw new Exception("对象申明中未配置需要字段映射的特性!");
}
#endregion
#endregion
dtResult.TableName = typeArr[0].Name;
foreach (PropertyInfo pi in domDomNotIngoredPropertyList)
{
object[] objFieldMapConverter = pi.GetCustomAttributes(typeof(DomFieldMapAttribute), true);
if (objFieldMapConverter != null && objFieldMapConverter.Length > 0)
{
var vMapAttr = (DomFieldMapAttribute)objFieldMapConverter[0];
AddColumnsWithColumnNameByDTOProperty(pi, vMapAttr.MappedFieldName, vMapAttr.MappedFieldSequence, ref dtResult);
}
}
for (int i = 0; i < sourceList.Count; i++)
{
ArrayList tempList = new ArrayList();
foreach (PropertyInfo pi in domDomNotIngoredPropertyList)
{
#region Bool类型转换 Myl190801
object[] objBoolConverter = pi.GetCustomAttributes(typeof(BoolConverterAttribute), true);
Type boolConvertType = null;
if (objBoolConverter != null && objBoolConverter.Length > 0)
{
boolConvertType = ((BoolConverterAttribute)objBoolConverter[0]).ConvertType;
}
#endregion
object obj = pi.GetValue(sourceList[i], null);
//V1.0.1
if (pi.PropertyType.IsEnum)
{
if (obj != null)
{
obj = ((int)Enum.Parse(pi.PropertyType, obj.ToString())).ToString();
}
}
else
{
//V1.0.3
if ((pi.PropertyType.IsGenericType) && (pi.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)))
{
if (pi.PropertyType.GetGenericArguments()[0].IsEnum)
{
if (obj != null)
{
obj = ((int)Enum.Parse(pi.PropertyType.GetGenericArguments()[0], obj.ToString())).ToString();
}
}
}
//V1.0.3
}
//V1.0.1
#region Bool类型转换 Myl190801
if (pi.PropertyType == typeof(bool))
{
if (boolConvertType != null)
{
if (obj != null)
{
obj = Convert.ChangeType(bool.Parse(obj.ToString()) ? ((BoolConverterAttribute)objBoolConverter[0]).BoolString[0] : ((BoolConverterAttribute)objBoolConverter[0]).BoolString[1], boolConvertType);
}
}
}
#endregion
tempList.Add(obj);
}
object[] array = tempList.ToArray();
dtResult.LoadDataRow(array, true);
}
#region
foreach (PropertyInfo pi in domDomNotIngoredPropertyList)
{
object[] objFieldMapConverter = pi.GetCustomAttributes(typeof(DomFieldMapAttribute), true);
if (objFieldMapConverter != null && objFieldMapConverter.Length > 0)
{
var vMapAttr = (DomFieldMapAttribute)objFieldMapConverter[0];
dtResult.Columns[vMapAttr.MappedFieldName].SetOrdinal(vMapAttr.MappedFieldSequence);
}
}
#endregion
dsResult.Tables.Add(dtResult);
return dsResult;
}
/// <summary>
/// DTO按照映射配置特性自动转换为DataSet数据集
/// </summary>
/// <param name="sourceList">数据源集合</param>
/// <returns></returns>
public static DataSet DTOToDataSetAutoConvertByAttribute(IList<TData> sourceList)
{
return DTOToDataSetAutoConvertByAttribute<TData>(sourceList);
}
public static DataSet AutoConvertSingleDTOToDataSetByAttribute(TData sourceData)
{
return DTOToDataSetAutoConvertByAttribute(new List<TData>() { sourceData });
}
private static void AddColumnsWithColumnNameByDTOProperty(PropertyInfo pi, string cColumnName, int? iMappedSequence, ref DataTable dtResult)
{
if (dtResult == null)
{
dtResult = new DataTable();
}
if (string.IsNullOrEmpty(cColumnName))
{
cColumnName = pi.Name;
}
if (dtResult.Columns.Contains(cColumnName))
{
return;
}
Type colType = pi.PropertyType;
#region Myl20190801
object[] objBoolConverter = pi.GetCustomAttributes(typeof(BoolConverterAttribute), true);
if (objBoolConverter != null && objBoolConverter.Length > 0)
{
colType = ((BoolConverterAttribute)objBoolConverter[0]).ConvertType;
}
#endregion
if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
{
if (colType.GetGenericArguments()[0].IsEnum)
{
colType = typeof(string);
}
else
{
colType = colType.GetGenericArguments()[0];
}
}
else if (colType.IsEnum)
{
colType = typeof(string);
}
dtResult.Columns.Add(new DataColumn(cColumnName, colType));
}
#endregion
#endregion
}
}