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 { /// /// 实体对象<->数据集转换帮助类 /// public static class DTOHelper 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(IList sourceList, params string[] propertyNameArray) where T : class { if (sourceList == null || sourceList.Count == 0) { return null; } List propertyNameList = new List(); 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 domDomNotIngoredPropertyList = domProperties.Where((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 sourceList, params string[] propertyNameArray) { return ConvertDTOToDataSet(sourceList, propertyNameArray); } public static DataSet ConvertSingleDTOToDataSet(TData sourceData, params string[] propertyNameArray) { return ConvertDTOToDataSet(new List() { sourceData }, propertyNameArray); } #endregion #region DataTable数据集->实体对象集合 #region DataTable利用泛型填充实体类 /// /// DataTable利用泛型填充实体类 /// /// 实体类类型 /// 待填充的DataTable /// /// 返回填充完的实体类对象集合 /// public static IList DataTableToList(DataTable dtData) where U : class { IList listObject = new List(); U t = default(U); PropertyInfo[] propertypes = null; string tempColumnName = string.Empty; foreach (DataRow eachRow in dtData.Rows) { t = Activator.CreateInstance(); 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利用泛型填充实体类 /// /// DataTable利用泛型填充实体类 /// /// 待填充的DataTable /// public static IList DataTableToList(DataTable dtData) { return DataTableToList(dtData); } /// /// DataTable利用泛型填充实体类,并制定特定的筛选条件 /// Myl 20210310 /// /// 待填充的DataTable /// 筛选条件 /// public static IList 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(); 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(DataRow adaptedRow, T value) where T : new() { T item = new T(); if (value == null || adaptedRow == null) { return item; } item = Activator.CreateInstance(); CopyToEntity(item, adaptedRow); return item; } public static TData ToEntity(DataRow adaptedRow, TData value) { return ToEntity(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 /// /// DTO按照映射配置特性自动转换为DataSet数据集 /// /// 泛型类型 /// 数据源集合 /// public static DataSet DTOToDataSetAutoConvertByAttribute(IList 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 domDomNotIngoredPropertyList = domProperties.Where((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; } /// /// DTO按照映射配置特性自动转换为DataSet数据集 /// /// 数据源集合 /// public static DataSet DTOToDataSetAutoConvertByAttribute(IList sourceList) { return DTOToDataSetAutoConvertByAttribute(sourceList); } public static DataSet AutoConvertSingleDTOToDataSetByAttribute(TData sourceData) { return DTOToDataSetAutoConvertByAttribute(new List() { 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 } }