Example #1
0
        private static NewExpression BuildNewExpression(ParameterExpression rootParameter, IReadOnlyDictionary <PropertyPath, ODataSelectColumnExpression> mapping)
        {
            // all paths longer than length 1 get grouped together and mapped to their own expression (this lets us support an arbitrary number of selected columns)
            var nestedProperties = mapping.Where(kvp => kvp.Key.Count > 1).ToArray();
            var nestedExpression = nestedProperties.Length > 0
                ? BuildNewExpression(rootParameter, nestedProperties.ToDictionary(kvp => kvp.Key.Skip(1).ToArray().As <PropertyPath>(), kvp => kvp.Value, PathComparer))
                : Expression.Constant(false).As <Expression>();

            // gather all argument expressions which will be used to initialize the type
            var arguments = ProjectionTypeProperties.Take(ProjectionTypeProperties.Count - 1)
                            .Select(prop =>
            {
                ODataSelectColumnExpression selectColumn;
                if (!mapping.TryGetValue(new[] { prop }, out selectColumn))
                {
                    return(Expression.Constant(false));
                }

                var selectColumnPropertyPath = Traverse.Along(selectColumn.Expression, c => c.Expression)
                                               .Select(m => m.Member)
                                               .Reverse();
                var expression = selectColumnPropertyPath.Aggregate(rootParameter.As <Expression>(), (acc, pi) => Expression.MakeMemberAccess(acc, pi));
                return(expression);
            })
                            .ToList();

            arguments.Add(nestedExpression);

            // build the new expression
            var parameterizedType = ProjectionType.MakeGenericType(arguments.Select(a => a.Type).ToArray());
            var newExpression     = Expression.New(
                parameterizedType.GetConstructors().Single(),
                arguments,
                members: parameterizedType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                );

            return(newExpression);
        }
Example #2
0
 /// <summary>
 /// Initializes a new assignment expression.
 /// </summary>
 /// <param name="left">The left operand of the assignment.</param>
 /// <param name="right">The right operand of the assignment.</param>
 /// <exception cref="ArgumentException"><paramref name="right"/> is not assignable to <paramref name="left"/>.</exception>
 public NullCoalescingAssignmentExpression(ParameterExpression left, Expression right)
     : this(left.As <Expression>(), right)
 {
 }