实现方式如下所示:
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Reflection; using System.Text.RegularExpressions; namespace HS.Helper { public static class DataTableHelper { #region DataTableConvertToList public static List<T> DataTableConvertToList<T>(this DataTable dataTable) where T : new() { List<T> result = new List<T>(); // 获取目标类型的属性信息 PropertyInfo[] properties = typeof(T).GetProperties(); foreach (DataRow row in dataTable.Rows) { T obj = new T(); foreach (PropertyInfo property in properties) { // 查找 DataTable 中与属性名匹配的列 DataColumn column = dataTable.Columns.Cast<DataColumn>() .FirstOrDefault(c => c.ColumnName.Equals(property.Name, StringComparison.OrdinalIgnoreCase)); if (column != null) { // 获取列的值 object value = row[column]; // 处理 DBNull 值 if (value != DBNull.Value) { // 根据列的类型转换值 Type targetType = property.PropertyType; object convertedValue = ConvertValue(value, targetType); property.SetValue(obj, convertedValue); } } } result.Add(obj); } return result; } private static object ConvertValue(object value, Type targetType) { try { // 根据目标类型进行转换 if (targetType == typeof(int)) return Convert.ToInt32(value); else if (targetType == typeof(string)) return Convert.ToString(value); else if (targetType == typeof(double)) return Convert.ToDouble(value); else if (targetType == typeof(decimal)) return Convert.ToDecimal(value); else if (targetType == typeof(bool)) return Convert.ToBoolean(value); else if (targetType == typeof(DateTime)) return Convert.ToDateTime(value); else return value; // 默认情况下返回原始值 } catch { // 如果转换失败,返回默认值 return Activator.CreateInstance(targetType); } } #endregion #region ConvertToList public static List<T> ConvertToList<T>(this DataTable dataTable) where T : new() { if (dataTable == null || dataTable.Rows.Count == 0) return new List<T>(); // 获取目标类型的属性信息 var properties = typeof(T).GetProperties() .Where(p => p.CanWrite) .ToList(); // 获取 DataTable 的所有列 //var columns = dataTable.Columns.Cast<DataColumn>(); //foreach (var column in columns) //{ // Console.WriteLine($"Column Name: {column.ColumnName}, Type: {column.DataType}"); //} var result = new List<T>(); foreach (DataRow row in dataTable.Rows) { T item = new T(); foreach (var property in properties) { // 查找匹配的列名 var columnName = property.Name; if (!dataTable.Columns.Contains(columnName)) continue; var value = row[columnName]; if (value == DBNull.Value) { // 如果目标类型是可空类型,则设置为null if (IsNullableType(property.PropertyType)) { property.SetValue(item, null); } else { // 如果目标类型不是可空类型,则设置为默认值 property.SetValue(item, GetDefaultValue(property.PropertyType)); } continue; } // 根据目标类型进行转换 if (property.PropertyType == typeof(string)) { property.SetValue(item, Convert.ToString(value)); } else if (property.PropertyType == typeof(int) || property.PropertyType == typeof(int?)) { if (value is string stringValue) { if (IsStringLooksLikeInt(stringValue)) { property.SetValue(item, Convert.ToInt32(stringValue)); } else { // 如果不是整数格式,则保留为字符串 property.SetValue(item, stringValue); } } else { property.SetValue(item, Convert.ToInt32(value)); } } else if (property.PropertyType == typeof(double) || property.PropertyType == typeof(double?)) { property.SetValue(item, Convert.ToDouble(value)); } else if (property.PropertyType == typeof(decimal) || property.PropertyType == typeof(decimal?)) { property.SetValue(item, Convert.ToDecimal(value)); } else if (property.PropertyType == typeof(bool) || property.PropertyType == typeof(bool?)) { property.SetValue(item, Convert.ToBoolean(value)); } else if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime?)) { property.SetValue(item, Convert.ToDateTime(value)); } else { // 其他类型直接尝试转换 property.SetValue(item, Convert.ChangeType(value, property.PropertyType)); } } result.Add(item); } return result; } private static bool IsNullableType(Type type) { return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); } private static object GetDefaultValue(Type type) { if (type.IsValueType) { return Activator.CreateInstance(type); } return null; } private static bool IsStringLooksLikeInt(string value) { // 检查字符串是否只包含数字 return Regex.IsMatch(value, @"^\d+$"); } #endregion } }
博客内容主要用于日常学习记录,内容比较随意,如有问题,还需谅解!!!