DeviceManager/DeviceRepair.Utils/DTOHelper.cs
2024-07-27 09:44:19 +08:00

705 lines
28 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 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
}
}