コード例 #1
0
 private Expression AddOrderByQueryForSource(Expression source, OrderByClause orderbyClause, Type elementType)
 {
     if (orderbyClause != null)
     {
         LambdaExpression orderByExpression =
             FilterBinder.Bind(orderbyClause, elementType, _model, _settings, _assembliesResolver);
         source = ExpressionHelpers.OrderBy(source, orderByExpression, elementType, orderbyClause.Direction);
     }
     return(source);
 }
コード例 #2
0
        internal static LambdaExpression Bind(IQueryable baseQuery, OrderByClause orderBy, Type elementType,
                                              ODataQueryContext context, ODataQuerySettings querySettings)
        {
            Contract.Assert(orderBy != null);
            Contract.Assert(elementType != null);
            Contract.Assert(context != null);

            FilterBinder binder = context.GetFilterBinder(querySettings);

            binder._filterType = elementType;
            binder.BaseQuery   = baseQuery;

            return(BindOrderByClause(binder, orderBy, elementType));
        }
コード例 #3
0
        internal static Expression Bind(IQueryable baseQuery, FilterClause filterClause, Type filterType,
                                        ODataQueryContext context, ODataQuerySettings querySettings)
        {
            Contract.Assert(filterClause != null);
            Contract.Assert(filterType != null);
            Contract.Assert(context != null);

            FilterBinder binder = context.GetFilterBinder(querySettings);

            binder._filterType = filterType;
            binder.BaseQuery   = baseQuery;

            return(BindFilterClause(binder, filterClause, filterType));
        }
コード例 #4
0
        internal static LambdaExpression BindFilterClause(FilterBinder binder, FilterClause filterClause, Type filterType)
        {
            LambdaExpression filter = binder.BindExpression(filterClause.Expression, filterClause.RangeVariable, filterType);

            filter = Expression.Lambda(binder.ApplyNullPropagationForFilterBody(filter.Body), filter.Parameters);

            Type expectedFilterType = typeof(Func <,>).MakeGenericType(filterType, typeof(bool));

            if (filter.Type != expectedFilterType)
            {
                throw Error.Argument("filterType", SRResources.CannotCastFilter, filter.Type.FullName, expectedFilterType.FullName);
            }

            return(filter);
        }
コード例 #5
0
        private static FilterBinder GetOrCreateFilterBinder(ODataQueryContext context, ODataQuerySettings querySettings)
        {
            FilterBinder binder = null;

            if (context.RequestContainer != null)
            {
                binder = context.RequestContainer.GetRequiredService <FilterBinder>();
                if (binder != null && binder.Model != context.Model && binder.Model == EdmCoreModel.Instance)
                {
                    binder.Model = context.Model;
                }
            }

            return(binder ?? new FilterBinder(querySettings, AssemblyResolverHelper.Default, context.Model));
        }
コード例 #6
0
        internal static Expression Bind(FilterClause filterClause, Type filterType, IEdmModel model,
                                        IAssemblyResolver assembliesResolver, ODataQuerySettings querySettings)
        {
            if (filterClause == null)
            {
                throw Error.ArgumentNull("filterClause");
            }
            if (filterType == null)
            {
                throw Error.ArgumentNull("filterType");
            }
            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }
            if (assembliesResolver == null)
            {
                throw Error.ArgumentNull("assembliesResolver");
            }

            FilterBinder binder = new FilterBinder(model, assembliesResolver, querySettings, filterType);

            return(BindFilterClause(binder, filterClause, filterType));
        }
コード例 #7
0
ファイル: SelectExpandBinder.cs プロジェクト: akorchev/odata
        internal Expression CreatePropertyValueExpressionWithFilter(IEdmEntityType elementType, IEdmProperty property,
                                                                    Expression source, FilterClause filterClause)
        {
            Contract.Assert(elementType != null);
            Contract.Assert(property != null);
            Contract.Assert(source != null);

            IEdmEntityType declaringType = property.DeclaringType as IEdmEntityType;

            Contract.Assert(declaringType != null, "only entity types are projected.");

            // derived property using cast
            if (elementType != declaringType)
            {
                Type castType = EdmLibHelpers.GetClrType(declaringType, _model);
                if (castType == null)
                {
                    throw new ODataException("TODO: " /*Error.Format(SRResources.MappingDoesNotContainResourceType,
                                                       * declaringType.FullName())*/);
                }

                source = Expression.TypeAs(source, castType);
            }

            string     propertyName          = EdmLibHelpers.GetClrPropertyName(property, _model);
            Expression propertyValue         = Expression.Property(source, propertyName);
            Type       nullablePropertyType  = propertyValue.Type.ToNullable();
            Expression nullablePropertyValue = ExpressionHelpers.ToNullable(propertyValue);

            if (filterClause != null && property.Type.IsCollection())
            {
                IEdmTypeReference edmElementType = property.Type.AsCollection().ElementType();
                Type clrElementType = EdmLibHelpers.GetClrType(edmElementType, _model);
                if (clrElementType == null)
                {
                    throw new ODataException("TODO:" /*Error.Format(SRResources.MappingDoesNotContainResourceType,
                                                      * edmElementType.FullName())*/);
                }

                Expression filterSource =
                    typeof(IEnumerable).IsAssignableFrom(source.Type.GetProperty(propertyName).PropertyType)
                        ? Expression.Call(
                        ExpressionHelperMethods.QueryableAsQueryable.MakeGenericMethod(clrElementType),
                        nullablePropertyValue)
                        : nullablePropertyValue;

                Expression           filterPredicate = FilterBinder.Bind(filterClause, clrElementType, /*_context.RequestContainer*/ null);
                MethodCallExpression filterResult    = Expression.Call(
                    ExpressionHelperMethods.QueryableWhereGeneric.MakeGenericMethod(clrElementType),
                    filterSource,
                    filterPredicate);

                nullablePropertyType = filterResult.Type;
                if (_settings.HandleNullPropagation == HandleNullPropagationOption.True)
                {
                    // nullablePropertyValue == null ? null : filterResult
                    nullablePropertyValue = Expression.Condition(
                        test: Expression.Equal(nullablePropertyValue, Expression.Constant(value: null)),
                        ifTrue: Expression.Constant(value: null, type: nullablePropertyType),
                        ifFalse: filterResult);
                }
                else
                {
                    nullablePropertyValue = filterResult;
                }
            }

            if (!property.Type.IsCollection())
            {
                if (_settings.HandleNullPropagation == HandleNullPropagationOption.True)
                {
                    // source == null ? null : propertyValue
                    propertyValue = Expression.Condition(
                        test: Expression.Equal(source, Expression.Constant(value: null)),
                        ifTrue: Expression.Constant(value: null, type: nullablePropertyType),
                        ifFalse: nullablePropertyValue);
                }
                else
                {
                    // need to cast this to nullable as EF would fail while materializing if the property is not nullable and source is null.
                    propertyValue = nullablePropertyValue;
                }
            }

            return(propertyValue);
        }
コード例 #8
0
        internal static LambdaExpression BindOrderByClause(FilterBinder binder, OrderByClause orderBy, Type elementType)
        {
            LambdaExpression orderByLambda = binder.BindExpression(orderBy.Expression, orderBy.RangeVariable, elementType);

            return(orderByLambda);
        }
コード例 #9
0
        internal Expression CreatePropertyValueExpressionWithFilter(IEdmEntityType elementType, IEdmProperty property,
                                                                    Expression source, FilterClause filterClause)
        {
            Contract.Assert(elementType != null);
            Contract.Assert(property != null);
            Contract.Assert(source != null);

            IEdmEntityType declaringType = property.DeclaringType as IEdmEntityType;

            Contract.Assert(declaringType != null, "only entity types are projected.");

            // derived property using cast
            if (elementType != declaringType)
            {
                Type castType = EdmLibHelpers.GetClrType(declaringType, _model);
                if (castType == null)
                {
                    throw new ODataException("TODO: " /*Error.Format(SRResources.MappingDoesNotContainResourceType,
                                                       * declaringType.FullName())*/);
                }

                source = Expression.TypeAs(source, castType);
            }

            string     propertyName          = EdmLibHelpers.GetClrPropertyName(property, _model);
            Expression propertyValue         = Expression.Property(source, propertyName);
            Type       nullablePropertyType  = propertyValue.Type.ToNullable();
            Expression nullablePropertyValue = ExpressionHelpers.ToNullable(propertyValue);

            Type       clrElementType       = EdmLibHelpers.GetClrType(elementType, _model);
            Expression filterSource         = null;
            var        interceptorContainer = new InterceptorContainer(clrElementType, _serviceProvider);

            if ((filterClause != null || interceptorContainer.Any) && property.Type.IsCollection())
            {
                if (clrElementType == null)
                {
                    throw new ODataException("TODO:" /*Error.Format(SRResources.MappingDoesNotContainResourceType,
                                                      * edmElementType.FullName())*/);
                }

                filterSource =
                    typeof(IEnumerable).IsAssignableFrom(source.Type.GetProperty(propertyName).PropertyType)
                        ? Expression.Call(
                        ExpressionHelperMethods.QueryableAsQueryable.MakeGenericMethod(clrElementType),
                        nullablePropertyValue)
                        : nullablePropertyValue;

                Expression           filterPredicate = FilterBinder.Bind(filterClause, clrElementType, _serviceProvider);
                MethodCallExpression filterResult    = Expression.Call(
                    ExpressionHelperMethods.QueryableWhereGeneric.MakeGenericMethod(clrElementType),
                    filterSource,
                    filterPredicate);

                nullablePropertyType = filterResult.Type;
                if (_settings.HandleNullPropagation == HandleNullPropagationOption.True)
                {
                    // nullablePropertyValue == null ? null : filterResult
                    nullablePropertyValue = Expression.Condition(
                        test: Expression.Equal(nullablePropertyValue, Expression.Constant(value: null)),
                        ifTrue: Expression.Constant(value: null, type: nullablePropertyType),
                        ifFalse: filterResult);
                }
                else
                {
                    nullablePropertyValue = filterResult;
                }
            }
            if ((filterClause != null || interceptorContainer.Any) && property.Type.IsCollection())
            {
                filterSource =
                    typeof(IEnumerable).IsAssignableFrom(source.Type.GetProperty(propertyName).PropertyType)
                        ? Expression.Call(
                        ExpressionHelperMethods.QueryableAsQueryable.MakeGenericMethod(clrElementType),
                        nullablePropertyValue)
                        : nullablePropertyValue;
            }
            // TODO: Fix possibly ambiguity resolution if the
            // implementation class has multiple methods names
            // "Intercept"
            var handleNull = false;

            source = ApplyInterceptors(source, clrElementType, _serviceProvider);
            //interceptorContainer.ForEach(source, (src, predicate) =>
            //{
            //    if (filterSource != null)
            //    {
            //        // We have a collection to intercept
            //        ApplyFilterToQuery(
            //            clrElementType,
            //            filterSource,
            //            predicate,
            //            ref nullablePropertyType,
            //            ref nullablePropertyValue);
            //    }
            //    else
            //    {
            //        handleNull = true;
            //        // Apply our predicate locally
            //        nullablePropertyValue = Expression.Condition(
            //            test: Expression.Invoke(predicate, nullablePropertyValue),
            //            ifTrue: propertyValue,
            //            ifFalse: Expression.Constant(value: null, type: nullablePropertyType)
            //            );

            //        //ApplyFilterToQuery(
            //        //    clrElementType,
            //        //    propertyValue,
            //        //    predicate,
            //        //    ref nullablePropertyType,
            //        //    ref nullablePropertyValue);
            //    }
            //});

            if (_settings.HandleNullPropagation == HandleNullPropagationOption.True)
            {
                // source == null ? null : propertyValue
                propertyValue = Expression.Condition(
                    test: Expression.Equal(source, Expression.Constant(value: null)),
                    ifTrue: Expression.Constant(value: null, type: nullablePropertyType),
                    ifFalse: nullablePropertyValue);
            }
            else
            {
                // need to cast this to nullable as EF would fail while materializing if the property is not nullable and source is null.
                propertyValue = nullablePropertyValue;
            }

            return(propertyValue);
        }