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 对象值映射赋值(属性名称根据被指映射)
///
/// 对象值映射赋值(属性名称和类型 映射,否者复默认值)
/// lz:231020
///
///
///
///
public static targetT MappingTo(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 resNameProDic = new Dictionary();
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 私有方法
///
/// 给属性赋值,类型不一致转换为对应类型
///
///
/// 返回的对象
/// 数据源属性
/// 被赋值的属性
/// 数据源属性值
private static void FillProValue(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);
}
}
///
/// 属性取值,拼装lambda表达式
///
///
/// 取值的属性
///
private static Func BuildGetLambda(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>(dataConvertToObject, exinstance);
return resLambda.Compile();
}
///
/// 属性赋值、拼装lambda表达式
///
///
/// 赋值的属性
///
private static Action BuildSetLambda(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>(lambdaBody, resParm, sourceParm);
return resLambda.Compile();
}
#endregion
}
}