实现方式如下所示:
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
}
}
博客内容主要用于日常学习记录,内容比较随意,如有问题,还需谅解!!!

浙公网安备 33010602011771号