TG.WXCRM.V4/Common/MappingExtension.cs

159 lines
6.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}