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