namespace ExtraLib.Extends
{
using System;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
public static class ModelReflector<T> where T : new()
{
#region 内部调用
/// <summary>
/// 获取实体模型属性
/// </summary>
/// <param name="name"></param>
/// <param name="useDisplayName"></param>
/// <returns></returns>
static PropertyInfo GetProperty(string name, bool useDisplayName = false)
{
if (!useDisplayName) return typeof(T).GetProperty(name);
// 使用特性名称索引
foreach (var property in GetProperties())
{
var displayName = property.GetCustomAttribute<DisplayNameAttribute>().DisplayName;
if (displayName == name) return property;
}
return null;
}
/// <summary>
/// 获取模型所有属性
/// </summary>
/// <returns></returns>
static PropertyInfo[] GetProperties()
{
return typeof(T).GetProperties().OrderBy(t => t.Name).ToArray();
}
#endregion
/// <summary>
/// 获取成员特性名称
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static string GetDisplayName(string name)
{
var property = GetProperty(name);
var attr = property.GetCustomAttribute<DisplayNameAttribute>();
var displayName = attr.DisplayName;
return displayName;
}
/// <summary>
/// 获取成员名称
/// </summary>
/// <param name="useDisplayName"></param>
/// <returns></returns>
public static string[] GetMemberNames(bool useDisplayName = false)
{
var properties = GetProperties();
return useDisplayName
? properties
.Select(t => t.GetCustomAttribute<DisplayNameAttribute>())
.Select(t => t.DisplayName)
.ToArray()
: properties
.Select(t => t.Name)
.ToArray();
}
/// <summary>
/// 获取成员值
/// </summary>
/// <param name="obj"></param>
/// <param name="name"></param>
/// <param name="useDisplayName"></param>
/// <returns></returns>
public static object GetMemberValue(T obj, string name, bool useDisplayName = false)
{
var property = GetProperty(name, useDisplayName);
return property.GetValue(obj);
}
/// <summary>
/// 设置成员值
/// </summary>
/// <param name="obj"></param>
/// <param name="name"></param>
/// <param name="value"></param>
/// <param name="useDisplayName"></param>
public static void SetMemberValue(T obj, string name, object value, bool useDisplayName = false)
{
var property = GetProperty(name, useDisplayName);
var type = property.PropertyType;
// 可为null的泛型处理
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
type = Nullable.GetUnderlyingType(type);
}
property.SetValue(obj, value == null ? null : Convert.ChangeType(value, type), null);
}
#region 模型映射
/// <summary>
/// 将实体模型映射为表格数据
/// </summary>
/// <param name="model"></param>
/// <param name="dt"></param>
/// <param name="useDisplayName"></param>
/// <returns></returns>
public static DataRow MapToRow(T model, DataTable dt, bool useDisplayName = false)
{
var dr = dt.NewRow();
for (var i = 0; i < dt.Columns.Count; i++)
{
var columnName = dt.Columns[i].ColumnName;
var property = GetProperty(columnName, useDisplayName);
if (property == null) continue;
// 赋值
var value = property.GetValue(model, null);
dr[i] = value;
}
return dr;
}
/// <summary>
/// 将实体模型映射为数据表控件数据
/// </summary>
/// <param name="model"></param>
/// <param name="dt"></param>
/// <param name="useDisplayName"></param>
/// <returns></returns>
public static DataGridViewRow MapToRow(T model, DataGridView dt, bool useDisplayName = false)
{
var dr = new DataGridViewRow();
dr.CreateCells(dt);// 根据模板新建列
for (var i = 0; i < dt.Columns.Count; i++)
{
var columnName = dt.Columns[i].Name;
var property = GetProperty(columnName, useDisplayName);
if (property == null) continue;
// 赋值
var value = property.GetValue(model, null);
dr.Cells[i].Value = value;
}
return dr;
}
/// <summary>
/// 将表格数据映射为实体模型
/// </summary>
/// <param name="dr"></param>
/// <param name="useDisplayName"></param>
/// <returns></returns>
public static T MapToModel(DataRow dr, bool useDisplayName = false)
{
var model = new T();
if (dr == null) return model;
var dt = dr.Table;
var rowIndex = dt.Rows.IndexOf(dr);
var row = dt.Rows[rowIndex];// 注意!!!DataRow的引用方式很特别,必须索引回数据表才有数据
for (var i = 0; i < dt.Columns.Count; i++)
{
var columnName = dt.Columns[i].ColumnName;
var property = GetProperty(columnName, useDisplayName);
var cell = row[i];
if (property == null || cell == DBNull.Value) continue;
// 赋值
var valueType = property.PropertyType;
var validValue = Convert.ChangeType(cell, valueType);
property.SetValue(model, validValue, null);
}
return model;
}
/// <summary>
/// 将数据表控件数据映射为实体模型
/// </summary>
/// <param name="dr"></param>
/// <param name="useDisplayName"></param>
/// <returns></returns>
public static T MapToModel(DataGridViewRow dr, bool useDisplayName = false)
{
var model = new T();
if (dr == null) return model;
var dt = dr.DataGridView;
for (var i = 0; i < dt.Columns.Count; i++)
{
var columnName = dt.Columns[i].Name;
var property = GetProperty(columnName, useDisplayName);
var cell = dr.Cells[i].Value;
if (property == null || cell == DBNull.Value) continue;
// 赋值
var valueType = property.PropertyType;
var validValue = Convert.ChangeType(cell, valueType);
property.SetValue(model, validValue, null);
}
return model;
}
#endregion
}
}