/// <summary>
        /// 创建公共成员
        /// </summary>
        protected void CreateCommonMember()
        {
            PropertyInfo[] propertiesSource = SourceType.GetProperties();
            foreach (PropertyInfo propSource in propertiesSource)
            {
                PropertyInfo propDest = TargetType.GetProperty(propSource.Name);
                if (propDest != null)
                {
                    // 检查是否已存在或被忽略。
                    bool ignorePropDest = _propertiesToIgnore.Exists(x => x.Name == propDest.Name) || PropertiesMapping.Exists(x => GetPropertyInfo(x.Item2).Name == propDest.Name);

                    if (propDest.CanWrite && !ignorePropDest)
                    {
                        Type sourceType = propSource.PropertyType;
                        Type destType = propDest.PropertyType;
                        bool isList = IsListOf(destType);
                        if (isList)
                        {
                            sourceType = TypeSystem.GetElementType(propSource.PropertyType);
                            destType = TypeSystem.GetElementType(propDest.PropertyType);
                        }

                        var canCreateConfig = CanCreateConfig(sourceType, destType);
                        if (canCreateConfig.CanCreate)
                        {
                            // 只创造现有的关系
                            Expression expSource = Expression.MakeMemberAccess(paramClassSource, propSource);
                            ParameterExpression paramDest = Expression.Parameter(TargetType, "t");
                            Expression expDest = Expression.MakeMemberAccess(paramDest, propDest);
                            PropertiesMapping.Add(Tuple.Create(expSource, expDest, false, canCreateConfig.MapperName));
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 获取排序表达式树
        /// </summary>
        /// <param name="propertySource">属性名</param>
        /// <returns></returns>
        public LambdaExpression GetSortedExpression(string propertySource)
        {
            var exp = PropertiesMapping.Find(x => GetPropertyInfo(x.Item2).Name == propertySource);
            if (exp == null)
            {
                throw new PropertyNoExistException(propertySource, TargetType);
            }

            // 更改参数
            var visitor = new MapperExpressionVisitor(paramClassSource);
            var result = visitor.Visit(exp.Item1);
            return Expression.Lambda(result, paramClassSource);
        }
        internal Expression GetLambdaDest(string propertyName)
        {
            var exp = PropertiesMapping.Find(x => GetPropertyInfo(x.Item1).Name == propertyName);
            if (exp != null)
            {
                var final = exp.Item2;
                if (final.NodeType == ExpressionType.Convert)
                {
                    final = (final as UnaryExpression).Operand;
                }

                return final;
            }

            return null;
        }
예제 #4
0
        internal LambdaExpression GetSortedExpression(string propertySource)
        {
            Contract.Requires(!string.IsNullOrEmpty(propertySource));
            Expression result = null;
            var        exp    = PropertiesMapping.Find(x => GetPropertyInfo(x.Item2).Name == propertySource);

            if (exp == null)
            {
                throw new PropertyNoExistException(propertySource, TargetType);
            }
            // To change the parameter.
            var visitor = new MapperExpressionVisitor(paramClassSource);

            result = visitor.Visit(exp.Item1);
            return(Expression.Lambda(result, paramClassSource));
        }
        /// <summary>
        /// 创建映射表达式树
        /// </summary>
        /// <param name="constructor"></param>
        public virtual void CreateMappingExpression(Func <Type, object> constructor)
        {
            if (!_isInitialized)
            {
                // 它是在处理前放置以避免递归循环。
                _isInitialized   = true;
                _constructorFunc = constructor;
                CreateCommonMember();
                var propsToAnalyse = PropertiesMapping.ToList(); // 克隆列表以便于更改。
                for (int i = 0; i < propsToAnalyse.Count; i++)
                {
                    var propToAnalyse = propsToAnalyse[i];
                    CheckAndConfigureMapping(ref propToAnalyse);
                    propsToAnalyse[i] = propToAnalyse;
                }

                PropertiesMapping = propsToAnalyse;
                // 编译
                GetDelegate();
            }
        }
예제 #6
0
        /// <summary>
        /// 反向映射
        /// </summary>
        /// <param name="name">mapper别名</param>
        /// <returns>
        /// 新的mapper对象
        /// </returns>
        /// <exception cref="MapperExistException"></exception>
        public MapperConfiguration <TDest, TSource> ReverseMap(string name = null)
        {
            var map = GetMapper(typeof(TDest), typeof(TSource), false, name);

            if (map != null)
            {
                throw new MapperExistException(typeof(TDest), typeof(TSource));
            }
            string finalName = string.IsNullOrEmpty(name) ? "s" + (MapperConfigurationCollectionContainer.Instance.Count).ToString() : name;

            map = new MapperConfiguration <TDest, TSource>(finalName);
            MapperConfigurationCollectionContainer.Instance.Add(map);
            CreateCommonMember();

            // 现有属性的映射,并且创建反向关系
            foreach (var item in PropertiesMapping.Where(item => GetPropertyInfo(item.Item1).CanWrite))
            {
                if (!string.IsNullOrEmpty(item.Item4))
                {
                    //找到反向关系的mapper
                    var reverseMapper = GetMapper(item.Item2.Type, item.Item1.Type, false);
                    if (reverseMapper != null)
                    {
                        map.ForMemberBase(item.Item2, item.Item1, item.Item3, reverseMapper.Name);
                    }
                }
                else
                {
                    if (item.Item1.NodeType == ExpressionType.MemberAccess)
                    {
                        map.ForMemberBase(item.Item2, item.Item1, item.Item3, item.Item4);
                    }
                }
            }

            return((MapperConfiguration <TDest, TSource>)map);
        }
 /// <summary>
 /// 将表达式源的映射分配给属性目标。
 /// </summary>
 /// <param name="getPropertySource">属性源类型</param>
 /// <param name="getPropertyDest">属性目标类型</param>
 /// <param name="checkIfNull">是否检查null值</param>
 /// <param name="name">要使用的映射器的别名</param>
 internal MapperConfigurationBase ForMemberBase(Expression getPropertySource, Expression getPropertyDest, bool checkIfNull, string name = null)
 {
     // 添加到映射列表并且可以继续操作
     PropertiesMapping.Add(Tuple.Create(getPropertySource, getPropertyDest, checkIfNull, name));
     return this;
 }