159 lines
6.0 KiB
C#
159 lines
6.0 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Linq.Expressions;
|
||
using System.Reflection;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace WX.CRM.Common
|
||
{
|
||
public static class MappingExtension
|
||
{
|
||
#region 对象值映射赋值(属性名称根据被指映射)
|
||
|
||
/// <summary>
|
||
/// 对象值映射赋值(属性名称和类型 映射,否者复默认值)
|
||
/// lz:231020
|
||
/// </summary>
|
||
/// <typeparam name="sourceT"></typeparam>
|
||
/// <typeparam name="targetT"></typeparam>
|
||
/// <param name="sourceInfo"></param>
|
||
public static targetT MappingTo<sourceT, targetT>(this sourceT sourceInfo) where sourceT : class, new() where targetT : class, new()
|
||
{
|
||
targetT result = default(targetT);
|
||
if (sourceInfo == null)
|
||
{
|
||
return result;
|
||
}
|
||
|
||
Type sourceType = typeof(sourceT);
|
||
Type targetType = typeof(targetT);
|
||
// 获取数据源public属性集合
|
||
PropertyInfo[] sourcePropertyInfoList = sourceType.GetProperties();
|
||
|
||
if (sourcePropertyInfoList != null)
|
||
{
|
||
// 获取返回的对象的共有属性的名称集合,数据源不存在的不需要做赋值
|
||
var resProList = targetType.GetProperties();
|
||
Dictionary<string, PropertyInfo> resNameProDic = new Dictionary<string, PropertyInfo>();
|
||
|
||
if (resProList != null)
|
||
{
|
||
foreach (var item in resProList)
|
||
{
|
||
resNameProDic.Add(item.Name, item);
|
||
}
|
||
}
|
||
|
||
//// 给对应(相同)的属性赋值
|
||
foreach (PropertyInfo sourcePropertyInfo in sourcePropertyInfoList)
|
||
{
|
||
string sourcePropertyInfoName = sourcePropertyInfo.Name;
|
||
|
||
if (resNameProDic.ContainsKey(sourcePropertyInfoName))
|
||
{
|
||
//// 获取数据源对应属性值
|
||
object sourceProValue = sourcePropertyInfo.GetValue(sourceInfo, null);
|
||
|
||
//// 给返回的对象相同属性赋值
|
||
FillProValue(result, sourcePropertyInfo, resNameProDic[sourcePropertyInfoName], sourceProValue);
|
||
}
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 私有方法
|
||
|
||
/// <summary>
|
||
/// 给属性赋值,类型不一致转换为对应类型
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="resObj">返回的对象</param>
|
||
/// <param name="sourceProperty">数据源属性</param>
|
||
/// <param name="resProperty">被赋值的属性</param>
|
||
/// <param name="sourcevalue">数据源属性值</param>
|
||
private static void FillProValue<T>(T resObj, PropertyInfo sourceProperty, PropertyInfo resProperty, object sourcevalue)
|
||
{
|
||
if (sourceProperty.PropertyType != resProperty.PropertyType)
|
||
{
|
||
|
||
if (!resProperty.PropertyType.IsGenericType)
|
||
{
|
||
var newValue = string.IsNullOrEmpty(sourcevalue?.ToString()) ? null : Convert.ChangeType(sourcevalue, resProperty.PropertyType);
|
||
//非泛型
|
||
resProperty.SetValue(resObj, newValue, null);
|
||
}
|
||
else
|
||
{
|
||
//泛型Nullable<>
|
||
Type genericTypeDefinition = resProperty.PropertyType.GetGenericTypeDefinition();
|
||
if (genericTypeDefinition == typeof(Nullable<>))
|
||
{
|
||
var newValue = string.IsNullOrEmpty(sourcevalue?.ToString()) ? null : Convert.ChangeType(sourcevalue, Nullable.GetUnderlyingType(resProperty.PropertyType));
|
||
resProperty.SetValue(resObj, newValue, null);
|
||
}
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
resProperty.SetValue(resObj, sourcevalue, null);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 属性取值,拼装lambda表达式
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="properInfo">取值的属性</param>
|
||
/// <returns></returns>
|
||
private static Func<T, object> BuildGetLambda<T>(this PropertyInfo properInfo)
|
||
{
|
||
//// 获取属性的对象类型
|
||
var targetType = properInfo.DeclaringType;
|
||
|
||
//// 定义属性的对象别名 t
|
||
var exinstance = Expression.Parameter(targetType, "t");
|
||
|
||
//// t.xxx
|
||
var lambdaBody = Expression.MakeMemberAccess(exinstance, properInfo);
|
||
|
||
//// 值转换为object类型
|
||
var dataConvertToObject = Expression.Convert(lambdaBody, typeof(object));
|
||
|
||
//// 定义lambda表达式并预编译
|
||
var resLambda = Expression.Lambda<Func<T, object>>(dataConvertToObject, exinstance);
|
||
return resLambda.Compile();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 属性赋值、拼装lambda表达式
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="properInfo">赋值的属性</param>
|
||
/// <returns></returns>
|
||
private static Action<T, object> BuildSetLambda<T>(this PropertyInfo properInfo)
|
||
{
|
||
var targetType = properInfo.DeclaringType;
|
||
var resParm = Expression.Parameter(targetType, "t");
|
||
var resBody = Expression.MakeMemberAccess(resParm, properInfo);
|
||
|
||
var sourceParm = Expression.Parameter(typeof(object), "p");
|
||
var sourceParmConvertedValue = Expression.Convert(sourceParm, properInfo.PropertyType);
|
||
var lambdaBody = Expression.Assign(resBody, sourceParmConvertedValue);
|
||
|
||
var resLambda = Expression.Lambda<Action<T, object>>(lambdaBody, resParm, sourceParm);
|
||
return resLambda.Compile();
|
||
}
|
||
#endregion
|
||
|
||
}
|
||
}
|