Files
2026-09-09 19:21:21 +08:00

155 lines
5.2 KiB
C#

using JinYuan.Models.HelperAttribute;
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
/// <summary>
/// DataTable 映射工具
/// </summary>
/// <summary>
/// DataTable 映射工具
/// </summary>
public static class DataTableMapper
{
/// <summary>
/// 实体类型转换为 DataTable 结构(含注解解析)
/// </summary>
public static DataTable ToSchema(Type type)
{
var dt = new DataTable(type.Name);
var members = type.GetMembers(BindingFlags.Public | BindingFlags.Instance);
foreach (var member in members)
{
var prop = member as PropertyInfo;
var field = member as FieldInfo;
if ((prop != null && !prop.CanRead) || (field == null && prop == null)) continue;
var attr = member.GetCustomAttribute<DataGridColumnAttribute>();
var colName = attr != null ? attr.ColumnName : member.Name;
var colType = attr != null && attr.ColumnType != null ? attr.ColumnType :
(prop != null ? prop.PropertyType : field.FieldType);
var column = dt.Columns.Add(colName, colType);
column.AllowDBNull = !(colType.GetTypeInfo().IsValueType &&
!colType.GetTypeInfo().IsGenericType);
}
return dt;
}
/// <summary>
/// 实体集合转换为 DataTable(含注解映射)
/// 使用: var dt = DataTableMapper.ToDataTable (employees, typeof (Employee));
/// </summary>
public static DataTable ToDataTable(this IEnumerable<object> entities, Type type)
{
var dt = ToSchema(type);
if (entities == null) return dt;
foreach (var entity in entities)
{
var row = dt.NewRow();
FillDataRow(entity, row, type);
dt.Rows.Add(row);
}
return dt;
}
private static void FillDataRow(object entity, DataRow row, Type type)
{
foreach (DataColumn column in row.Table.Columns)
{
MemberInfo member = null;
foreach (var m in type.GetMembers(BindingFlags.Public | BindingFlags.Instance))
{
var attr = m.GetCustomAttribute<DataGridColumnAttribute>();
var mName = attr != null ? attr.ColumnName : m.Name;
if (string.Equals(mName, column.ColumnName, StringComparison.OrdinalIgnoreCase))
{
member = m;
break;
}
}
if (member == null) continue;
object value;
if (member is PropertyInfo prop)
{
value = prop.GetValue(entity);
}
else if (member is FieldInfo field)
{
value = field.GetValue(entity);
}
else
{
continue;
}
row[column] = value ?? DBNull.Value;
}
}
/// <summary>
/// DataTable 转换为 List<T>
/// 使用案例: var employeeList = dt.ToList<Employee>();
/// </summary>
public static List<T> ToList<T>(this DataTable dt) where T : new()
{
var list = new List<T>();
var type = typeof(T);
var members = type.GetMembers(BindingFlags.Public | BindingFlags.Instance);
foreach (DataRow row in dt.Rows)
{
var item = new T();
foreach (var member in members)
{
var prop = member as PropertyInfo;
var field = member as FieldInfo;
if ((prop != null && !prop.CanWrite) || (field == null && prop == null)) continue;
var attr = member.GetCustomAttribute<DataGridColumnAttribute>();
var colName = attr != null ? attr.ColumnName : member.Name;
if (dt.Columns.Contains(colName))
{
var value = row[colName];
if (value != DBNull.Value)
{
if (prop != null)
{
prop.SetValue(item, Convert.ChangeType(value, prop.PropertyType));
}
else if (field != null)
{
field.SetValue(item, Convert.ChangeType(value, field.FieldType));
}
}
}
}
list.Add(item);
}
return list;
}
/// <summary>
/// 循环获取当前 DataTable 的列名称,通过自定义的获取名称方法获取新的列名并替换
/// </summary>
/// <param name="dt">要处理的 DataTable</param>
/// <param name="getNewColumnName">自定义的获取新列名的方法</param>
/// <returns>列名替换后的 DataTable</returns>
public static DataTable ReplaceColumnNamesWithCustomMethod(this DataTable dt, Func<string, string> GetNewColumnName)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
string originalColumnName = dt.Columns[i].ColumnName;
string newColumnName = GetNewColumnName(originalColumnName);
dt.Columns[i].ColumnName = newColumnName;
}
return dt;
}
}