示例#1
0
        private static MemberAssignment BuildCustomBinding(BaseProjectionConfig config, ParameterExpression parameterExpression, PropertyInfo destinationProperty)
        {
            var expression = config.Expressions.FirstOrDefault(c => c.DestinationMemberName == destinationProperty.Name);

            if (expression != null)
            {
                var lambda = expression.SourceExpression as LambdaExpression;
                if (lambda != null)
                {
                    var rightExp = new ParameterRenamer().Rename(lambda.Body, parameterExpression);
                    return(Expression.Bind(destinationProperty, rightExp));
                }
            }

            return(null);
        }
示例#2
0
        private static MemberAssignment BuildBinding(Expression parameterExpression, MemberInfo destinationProperty, IEnumerable <PropertyInfo> sourceProperties,
                                                     BaseProjectionConfig config, Dictionary <int, int> parameterIndexs, int index, string sourcePropertyName = null)
        {
            var destPropertyType = ((PropertyInfo)destinationProperty).PropertyType;

            //if ((destPropertyType.IsClass && destPropertyType != typeof(string)) || (destPropertyType.IsGenericType &&
            //        destPropertyType != typeof(string) && destPropertyType.GetInterfaces().Any(t => t.Name == "IEnumerable")))
            //{
            int propertyHashCode = destinationProperty.GetHashCode();

            if (parameterIndexs.ContainsKey(propertyHashCode))
            {
                parameterIndexs[propertyHashCode] = parameterIndexs[propertyHashCode] + 1;
            }
            else
            {
                parameterIndexs.Add(propertyHashCode, 1);
            }

            int maxDepth = 3;

            if (config != null && config.MaxDepth > 0)
            {
                maxDepth = config.MaxDepth;
            }

            if (parameterIndexs[propertyHashCode] >= maxDepth)
            {
                return(null);
            }
            //}

            if (!string.IsNullOrEmpty(sourcePropertyName))
            {
                parameterExpression = Expression.Property(parameterExpression, parameterExpression.Type.GetProperty(sourcePropertyName));
            }

            var sourceProperty = sourceProperties.FirstOrDefault(src => src.Name == destinationProperty.Name);

            if (sourceProperty != null)
            {
                if (destPropertyType.IsClass && destPropertyType != typeof(string) && destPropertyType != sourceProperty.PropertyType)
                {
                    var sProperties = sourceProperty.PropertyType.GetProperties();
                    var dProperties = destPropertyType.GetProperties().Where(dest => dest.CanWrite);

                    var bindings = dProperties
                                   .Select(dProperty => BuildBinding(parameterExpression, dProperty, sProperties, config, parameterIndexs, index, destinationProperty.Name))
                                   .Where(binding => binding != null);

                    var newMemberExpression = Expression.MemberInit(Expression.New(destPropertyType), bindings);
                    if (sourceProperty.PropertyType.GetCustomAttribute <ComplexTypeAttribute>() != null)
                    {
                        return(Expression.Bind(destinationProperty, newMemberExpression));
                    }

                    var nullCheck = Expression.Equal(Expression.Property(parameterExpression, sourceProperty), Expression.Constant(null, sourceProperty.PropertyType));

                    var convertExp = Expression.Constant(null, destPropertyType);

                    var conditionExpression = Expression.Condition(nullCheck, convertExp, newMemberExpression);

                    return(Expression.Bind(destinationProperty, conditionExpression));
                }

                if (sourceProperty.PropertyType.IsCollection() && destPropertyType.IsCollection())
                {
                    var sourceGenericArgument      = sourceProperty.PropertyType.GetGenericArguments()[0];
                    var destinationGenericArgument = destPropertyType.GetGenericArguments()[0];

                    var expression = typeof(ProjectionExpression <>).MakeGenericType(sourceGenericArgument)
                                     .GetMethod("BuildExpression", BindingFlags.NonPublic | BindingFlags.Static)
                                     .MakeGenericMethod(destinationGenericArgument)
                                     .Invoke(null, new object[] { parameterIndexs, ++index });

                    MethodCallExpression selectExpression = Expression.Call(
                        typeof(Enumerable),
                        "Select",
                        new[] { sourceGenericArgument, destinationGenericArgument },
                        Expression.Property(parameterExpression, sourceProperty),
                        (Expression)expression);

                    return(Expression.Bind(destinationProperty, selectExpression));
                }

                Expression rightExp = Expression.Property(parameterExpression, sourceProperty);

                if (destPropertyType != sourceProperty.PropertyType)
                {
                    rightExp = Expression.Convert(rightExp, destPropertyType);
                }

                return(Expression.Bind(destinationProperty, rightExp));
            }


            sourceProperty = sourceProperties.FirstOrDefault(p => p.PropertyType.IsClass &&
                                                             p.PropertyType != typeof(string) &&
                                                             destinationProperty.Name.StartsWith(p.Name));

            if (sourceProperty != null)
            {
                var sourceChildProperty = sourceProperty.PropertyType.GetProperties().FirstOrDefault(src => src.Name == destinationProperty.Name.Substring(sourceProperty.Name.Length).TrimStart('_'));

                if (sourceChildProperty != null)
                {
                    Expression childExp = Expression.Property(Expression.Property(parameterExpression, sourceProperty), sourceChildProperty);

                    Type destinationPropertyType = ((PropertyInfo)destinationProperty).PropertyType;
                    if (sourceChildProperty.PropertyType != destinationPropertyType)
                    {
                        childExp = Expression.Convert(childExp, destinationPropertyType);
                    }
                    if (sourceProperty.PropertyType.GetCustomAttribute <ComplexTypeAttribute>() != null)
                    {
                        return(Expression.Bind(destinationProperty, childExp));
                    }

                    var        nullCheck = Expression.Equal(Expression.Property(parameterExpression, sourceProperty), Expression.Constant(null, sourceProperty.PropertyType));
                    Expression defaultValueExp;
                    if (destinationPropertyType.IsValueType && !ReflectionUtils.IsNullable(destinationPropertyType))
                    {
                        defaultValueExp = Expression.Constant(ActivatorExtensions.CreateInstance(destinationPropertyType));
                    }
                    else
                    {
                        defaultValueExp = Expression.Constant(null, destinationPropertyType);
                    }
                    var conditionExpression = Expression.Condition(nullCheck, defaultValueExp, childExp);

                    return(Expression.Bind(destinationProperty, conditionExpression));
                }
            }

            return(null);
        }
示例#3
0
 private static bool HasCustomExpression(BaseProjectionConfig config, PropertyInfo pi)
 {
     return(config != null && config.Expressions.Any(c => c.DestinationMemberName == pi.Name));
 }