Exemple #1
0
        public static Expression DateTimeOffsetToDateTime(Expression expression, TimeZoneInfo timeZoneInfo, ODataQuerySettings settings)
        {
            var unaryExpression = expression as UnaryExpression;

            if (unaryExpression != null)
            {
                if (Nullable.GetUnderlyingType(unaryExpression.Type) == unaryExpression.Operand.Type)
                {
                    // this is a cast from T to Nullable<T> which is redundant.
                    expression = unaryExpression.Operand;
                }
            }
            var parameterizedConstantValue = ExtractParameterizedConstant(expression);
            var dto = parameterizedConstantValue as DateTimeOffset?;

            if (dto != null)
            {
                if (settings.EnableConstantParameterization)
                {
                    return(LinqParameterContainer.Parameterize(typeof(DateTime), EdmPrimitiveHelper.ConvertPrimitiveValue(dto.Value, typeof(DateTime), timeZoneInfo)));
                }
                else
                {
                    return(Expression.Constant(EdmPrimitiveHelper.ConvertPrimitiveValue(dto.Value, typeof(DateTime), timeZoneInfo), typeof(DateTime)));
                }
            }
            return(expression);
        }
        // Extract the constant that would have been encapsulated into LinqParameterContainer if this
        // expression represents it else return null.
        internal static object ExtractParameterizedConstant(Expression expression)
        {
            if (expression.NodeType == ExpressionType.MemberAccess)
            {
                MemberExpression memberAccess = expression as MemberExpression;
                Contract.Assert(memberAccess != null);

                PropertyInfo propertyInfo = memberAccess.Member as PropertyInfo;
                if (propertyInfo != null && propertyInfo.GetMethod.IsStatic)
                {
                    return(propertyInfo.GetValue(new object()));
                }

                if (memberAccess.Expression.NodeType == ExpressionType.Constant)
                {
                    ConstantExpression constant = memberAccess.Expression as ConstantExpression;
                    Contract.Assert(constant != null);
                    Contract.Assert(constant.Value != null);
                    LinqParameterContainer value = constant.Value as LinqParameterContainer;
                    Contract.Assert(value != null, "Constants are already embedded into LinqParameterContainer");

                    return(value.Property);
                }
            }

            return(null);
        }
        public static IQueryable Skip(IQueryable query, int count, Type type, bool parameterize)
        {
            MethodInfo skipMethod          = ExpressionHelperMethods.QueryableSkipGeneric.MakeGenericMethod(type);
            Expression skipValueExpression = parameterize ? LinqParameterContainer.Parameterize(typeof(int), count) : Expression.Constant(count);

            Expression skipQuery = Expression.Call(null, skipMethod, new[] { query.Expression, skipValueExpression });

            return(query.Provider.CreateQuery(skipQuery));
        }
Exemple #4
0
        public static Expression Parameterize(Type type, object value)
        {
            // () => new LinqParameterContainer(constant).Property
            // instead of returning a constant expression node, wrap that constant in a class the way compiler
            // does a closure, so that EF can parameterize the constant (resulting in better performance due to expression translation caching).
            LinqParameterContainer containedValue = LinqParameterContainer.Create(type, value);

            return(Expression.Property(Expression.Constant(containedValue), "TypedProperty"));
        }
        public IQueryable Bind(IQueryable query)
        {
            PreprocessQuery(query);
            // compute(X add Y as Z, A mul B as C) adds new properties to the output
            // Should return following expression
            // .Select($it => new ComputeWrapper<T> {
            //      Instance = $it,
            //      ModelID = 'Guid',
            //      Container => new AggregationPropertyContainer() {
            //          Name = "X",
            //          Value = $it.X + $it.Y,
            //          Next = new LastInChain() {
            //              Name = "C",
            //              Value = $it.A * $it.B
            //      }
            // })

            List <MemberAssignment> wrapperTypeMemberAssignments = new List <MemberAssignment>();

            // Set Instance property
            var wrapperProperty = this.ResultClrType.GetProperty("Instance");

            wrapperTypeMemberAssignments.Add(Expression.Bind(wrapperProperty, this.LambdaParameter));
            var properties = new List <NamedPropertyExpression>();

            foreach (var computeExpression in this._transformation.Expressions)
            {
                properties.Add(new NamedPropertyExpression(Expression.Constant(computeExpression.Alias), CreateComputeExpression(computeExpression)));
            }

            // Initialize property 'ModelID' on the wrapper class.
            // source = new Wrapper { ModelID = 'some-guid-id' }
            wrapperProperty = this.ResultClrType.GetProperty("ModelID");
            var wrapperPropertyValueExpression = QuerySettings.EnableConstantParameterization ?
                                                 LinqParameterContainer.Parameterize(typeof(string), _modelID) :
                                                 Expression.Constant(_modelID);

            wrapperTypeMemberAssignments.Add(Expression.Bind(wrapperProperty, wrapperPropertyValueExpression));

            // Set new compute properties
            wrapperProperty = ResultClrType.GetProperty("Container");
            wrapperTypeMemberAssignments.Add(Expression.Bind(wrapperProperty, AggregationPropertyContainer.CreateNextNamedPropertyContainer(properties)));

            var initilizedMember =
                Expression.MemberInit(Expression.New(ResultClrType), wrapperTypeMemberAssignments);
            var selectLambda = Expression.Lambda(initilizedMember, this.LambdaParameter);

            var result = ExpressionHelpers.Select(query, selectLambda, this.ElementType);

            return(result);
        }
        public IQueryable Bind(IQueryable query)
        {
            PreprocessQuery(query);
            // compute(X add Y as Z, A mul B as C) adds new properties to the output
            // Should return following expression
            // .Select($it => new ComputeWrapper<T> {
            //      Instance = $it,
            //      Model = parametrized(IEdmModel),
            //      Container => new AggregationPropertyContainer() {
            //          Name = "X",
            //          Value = $it.X + $it.Y,
            //          Next = new LastInChain() {
            //              Name = "C",
            //              Value = $it.A * $it.B
            //      }
            // })

            List <MemberAssignment> wrapperTypeMemberAssignments = new List <MemberAssignment>();

            // Set Instance property
            var wrapperProperty = this.ResultClrType.GetProperty("Instance");

            wrapperTypeMemberAssignments.Add(Expression.Bind(wrapperProperty, this.LambdaParameter));
            var properties = new List <NamedPropertyExpression>();

            foreach (var computeExpression in this._transformation.Expressions)
            {
                properties.Add(new NamedPropertyExpression(Expression.Constant(computeExpression.Alias), CreateComputeExpression(computeExpression)));
            }

            // Initialize property 'Model' on the wrapper class.
            // source = new Wrapper { Model = parameterized(a-edm-model) }
            // Always parameterize as EntityFramework does not let you inject non primitive constant values (like IEdmModel).
            wrapperProperty = this.ResultClrType.GetProperty("Model");
            var wrapperPropertyValueExpression = LinqParameterContainer.Parameterize(typeof(IEdmModel), _model);

            wrapperTypeMemberAssignments.Add(Expression.Bind(wrapperProperty, wrapperPropertyValueExpression));

            // Set new compute properties
            wrapperProperty = ResultClrType.GetProperty("Container");
            wrapperTypeMemberAssignments.Add(Expression.Bind(wrapperProperty, AggregationPropertyContainer.CreateNextNamedPropertyContainer(properties)));

            var initilizedMember =
                Expression.MemberInit(Expression.New(ResultClrType), wrapperTypeMemberAssignments);
            var selectLambda = Expression.Lambda(initilizedMember, this.LambdaParameter);

            var result = ExpressionHelpers.Select(query, selectLambda, this.ElementType);

            return(result);
        }
        public static Expression Take(Expression source, int count, Type elementType, bool parameterize)
        {
            MethodInfo takeMethod;

            if (typeof(IQueryable).IsAssignableFrom(source.Type))
            {
                takeMethod = ExpressionHelperMethods.QueryableTakeGeneric.MakeGenericMethod(elementType);
            }
            else
            {
                takeMethod = ExpressionHelperMethods.EnumerableTakeGeneric.MakeGenericMethod(elementType);
            }

            Expression takeValueExpression = parameterize ? LinqParameterContainer.Parameterize(typeof(int), count) : Expression.Constant(count);
            Expression takeQuery           = Expression.Call(null, takeMethod, new[] { source, takeValueExpression });

            return(takeQuery);
        }
        public static Expression Skip(Expression source, int count, Type type, bool parameterize)
        {
            MethodInfo skipMethod;

            if (typeof(IQueryable).IsAssignableFrom(source.Type))
            {
                skipMethod = ExpressionHelperMethods.QueryableSkipGeneric.MakeGenericMethod(type);
            }
            else
            {
                skipMethod = ExpressionHelperMethods.EnumerableSkipGeneric.MakeGenericMethod(type);
            }

            Expression skipValueExpression = parameterize ? LinqParameterContainer.Parameterize(typeof(int), count) : Expression.Constant(count);
            Expression skipQuery           = Expression.Call(null, skipMethod, new[] { source, skipValueExpression });

            return(skipQuery);
        }
        // Extract the constant that would have been encapsulated into LinqParameterContainer if this
        // expression represents it else return null.
        internal static object ExtractParameterizedConstant(Expression expression)
        {
            if (expression.NodeType == ExpressionType.MemberAccess)
            {
                MemberExpression memberAccess = expression as MemberExpression;
                Contract.Assert(memberAccess != null);
                if (memberAccess.Expression.NodeType == ExpressionType.Constant)
                {
                    ConstantExpression constant = memberAccess.Expression as ConstantExpression;
                    Contract.Assert(constant != null);
                    Contract.Assert(constant.Value != null);
                    LinqParameterContainer value = constant.Value as LinqParameterContainer;
                    Contract.Assert(value != null, "Constants are already embedded into LinqParameterContainer");

                    return(value.Property);
                }
            }

            return(null);
        }