public void TranslatorShouldTranslateCastFunctionCallWithTwoParameters()
        {
            ConstantNode constantNode;

            this.testSubject = this.CreateTestSubjectWithEdmStringLiteral(out constantNode);
            this.TestFunctionCall <object, string>("cast", new[] { Parameter <object>("o"), constantNode }, o => (string)o, this.testSubject);
        }
Ejemplo n.º 2
0
        private NodeToExpressionTranslator CreateTestSubject(
            DataServiceBehavior dataServiceBehavior             = null,
            FunctionExpressionBinder expressionBinder           = null,
            Action <ODataProtocolVersion> verifyProtocolVersion = null,
            Action <ODataProtocolVersion> verifyRequestVersion  = null)
        {
            if (dataServiceBehavior == null)
            {
                dataServiceBehavior = new DataServiceBehavior();
            }

            if (expressionBinder == null)
            {
                expressionBinder = this.functionExpressionBinder;
            }

            if (verifyProtocolVersion == null)
            {
                verifyProtocolVersion = v => { };
            }

            if (verifyRequestVersion == null)
            {
                verifyRequestVersion = v => { };
            }

            return(NodeToExpressionTranslator.CreateForTests(
                       expressionBinder,
                       dataServiceBehavior,
                       new object(),
                       false,
                       this.implicitParameterExpression,
                       verifyProtocolVersion,
                       verifyRequestVersion));
        }
        public void TranslatorShouldTranslateIsOfFunctionCallWithTwoParameters()
        {
            ConstantNode constantNode;

            this.testSubject = this.CreateTestSubjectWithEdmStringLiteral(out constantNode);
            this.TestFunctionCall <object, bool>("isof", new[] { Parameter <object>("o"), constantNode }, o => o is string, this.testSubject);
        }
 public void TranslatorShouldTranslateReplaceIfEnabled()
 {
     this.testSubject = this.CreateTestSubject(new DataServiceBehavior {
         AcceptReplaceFunctionInQuery = true
     });
     this.TestFunctionCall <string, string>("replace", new[] { Parameter <string>("s"), Constant("foo"), Constant("bar") }, s => s.Replace("foo", "bar"), this.testSubject);
 }
        public void TranslatorShouldRequireProtocolVersionThreeForSingletonTypeSegment()
        {
            ODataProtocolVersion validatedProtocolVersion = ODataProtocolVersion.V4;

            this.testSubject = this.CreateTestSubject(verifyProtocolVersion: v => { validatedProtocolVersion = v; }, verifyRequestVersion: v => { throw new Exception("Should not be called."); });

            QueryNode node = new SingleResourceCastNode(this.EntityParameter <Customer>("o"), this.customerEdmType);

            this.testSubject.TranslateNode(node);
            validatedProtocolVersion.Should().Be(ODataProtocolVersion.V4);
        }
        public void TranslatorShouldRequireProtocolAndRequestVersionThreeForAnyAndAll()
        {
            ODataProtocolVersion validatedProtocolVersion = ODataProtocolVersion.V4;
            ODataProtocolVersion validatedRequestVersion  = ODataProtocolVersion.V4;

            this.testSubject = this.CreateTestSubject(verifyProtocolVersion: v => { validatedProtocolVersion = v; }, verifyRequestVersion: v => { validatedRequestVersion = v; });

            LambdaNode node = new AnyNode(new Collection <RangeVariable>(), null);

            node.Body   = Constant(true);
            node.Source = this.CollectionNavigationFromParameter("o");

            this.testSubject.TranslateNode(node);
            validatedProtocolVersion.Should().Be(ODataProtocolVersion.V4);
            validatedRequestVersion.Should().Be(ODataProtocolVersion.V4);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Apply filter to the given resouce expression
        /// </summary>
        /// <param name="rootExpression"></param>
        /// <param name="entityInstanceType"></param>
        /// <param name="uriParser"></param>
        /// <param name="filterClause"></param>
        /// <returns></returns>
        public static Expression ApplyFilter(this Expression rootExpression, Type entityInstanceType, ODataUriParser uriParser, FilterClause filterClause)
        {
            ParameterExpression parameter = Expression.Parameter(entityInstanceType, "it");
            NodeToExpressionTranslator nodeToExpressionTranslator = new NodeToExpressionTranslator()
            {
                ImplicitVariableParameterExpression = parameter,
                UriParser = uriParser,
            };
            Expression filterNodeExpression = nodeToExpressionTranslator.TranslateNode(filterClause.Expression);

            // IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
            // translate to rootExpression.Where(filterNodeExpression)
            return Expression.Call(
                typeof(Enumerable),
                "Where",
                new Type[] { entityInstanceType },
                rootExpression,
                Expression.Lambda(filterNodeExpression, parameter));
        }
Ejemplo n.º 8
0
        /// <summary>Filters a query like a SQL WHERE clause does.</summary>
        /// <param name="service">Service with data and configuration.</param>
        /// <param name="requestDescription">RequestDescription instance containing information about the current request being parsed.</param>
        /// <param name="source">Original source for query expression.</param>
        /// <returns>The composed query expression.</returns>
        internal static Expression Where(IDataService service, RequestDescription requestDescription, Expression source)
        {
            Debug.Assert(service != null, "service != null");
            Debug.Assert(source != null, "source != null");
            Debug.Assert(requestDescription != null, "requestDescription != null");

            FilterClause filterClause = new RequestExpressionParser(service, requestDescription).ParseFilter();

            if (filterClause == null)
            {
                return(source);
            }

            bool filterQueryApplicable = requestDescription.TargetKind == RequestTargetKind.Resource ||
                                         requestDescription.TargetKind == RequestTargetKind.OpenProperty ||
                                         requestDescription.TargetKind == RequestTargetKind.ComplexObject ||
                                         requestDescription.CountOption == RequestQueryCountOption.CountSegment;

            if (!filterQueryApplicable)
            {
                throw DataServiceException.CreateBadRequestError(Strings.RequestQueryProcessor_QueryFilterOptionNotApplicable);
            }

            Type queryElementType = source.ElementType();

            Debug.Assert(queryElementType != null, "queryElementType != null");

            ParameterExpression parameterForIt = Expression.Parameter(queryElementType, "it");

            Debug.Assert(
                (requestDescription.TargetResourceSet == null && (requestDescription.TargetResourceType == null || requestDescription.TargetResourceType.ResourceTypeKind != ResourceTypeKind.EntityType)) ||
                (requestDescription.TargetResourceType != null && requestDescription.TargetResourceType.ResourceTypeKind == ResourceTypeKind.EntityType),
                "setForIt cannot be null if typeForIt is an entity type.");
            Debug.Assert(
                requestDescription.TargetResourceType == null && parameterForIt.Type == typeof(object) ||
                requestDescription.TargetResourceType != null && requestDescription.TargetResourceType.InstanceType == parameterForIt.Type,
                "non-open type expressions should have a typeForIt");

            var translator          = NodeToExpressionTranslator.Create(service, requestDescription, parameterForIt);
            LambdaExpression lambda = translator.TranslateFilterClause(filterClause);

            return(source.QueryableWhere(lambda));
        }
 /// <summary>
 /// Initializes a new instance of <see cref="SkipTokenExpressionBuilder"/>.
 /// </summary>
 /// <param name="nodeToExpressionTranslator">The node to expression translator to use</param>
 internal SkipTokenExpressionBuilder(NodeToExpressionTranslator nodeToExpressionTranslator)
 {
     this.nodeToExpressionTranslator = nodeToExpressionTranslator;
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Initializes a new instance of <see cref="SkipTokenExpressionBuilder"/>.
 /// </summary>
 /// <param name="nodeToExpressionTranslator">The node to expression translator to use</param>
 internal SkipTokenExpressionBuilder(NodeToExpressionTranslator nodeToExpressionTranslator)
 {
     this.nodeToExpressionTranslator = nodeToExpressionTranslator;
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Apply thenOrderBy to the given resouce expression
        /// </summary>
        /// <param name="rootExpression"></param>
        /// <param name="entityInstanceType"></param>
        /// <param name="uriParser"></param>
        /// <param name="thenBy"></param>
        /// <returns></returns>
        public static Expression ApplyThenBy(this Expression rootExpression, Type entityInstanceType, ODataUriParser uriParser, OrderByClause thenBy)
        {
            ParameterExpression parameter = Expression.Parameter(entityInstanceType, "it");
            NodeToExpressionTranslator nodeToExpressionTranslator = new NodeToExpressionTranslator()
            {
                ImplicitVariableParameterExpression = parameter,
                UriParser = uriParser,
            };
            Expression orderByNodeExpression = nodeToExpressionTranslator.TranslateNode(thenBy.Expression);

            var keyType = EdmClrTypeUtils.GetInstanceType(thenBy.Expression.TypeReference);
            var method = thenBy.Direction == OrderByDirection.Ascending ? "ThenBy" : "ThenByDescending";
            //ThenBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
            return Expression.Call(
                typeof(Enumerable),
                method,
                new Type[] { entityInstanceType, keyType },
                rootExpression,
                Expression.Lambda(orderByNodeExpression, parameter));
        }
Ejemplo n.º 12
0
        private void TestFunctionCall <TParam, TReturn>(string functionName, IEnumerable <SingleValueNode> parameters, Expression <Func <TParam, TReturn> > expectedExpression, NodeToExpressionTranslator translator = null)
        {
            if (translator == null)
            {
                translator = this.testSubject;
            }

            var node   = new SingleValueFunctionCallNode(functionName, parameters, null);
            var result = translator.TranslateNode(node);

            CompareExpressions(expectedExpression.Body, result);
        }
Ejemplo n.º 13
0
        public NodeToExpressionTranslatorTests()
        {
            this.functionExpressionBinder = new FunctionExpressionBinder(t => { throw new Exception(); });

            this.customerResourceType = new ResourceType(typeof(Customer), ResourceTypeKind.EntityType, null, "Fake", "Customer", false)
            {
                IsOpenType = true
            };
            var derivedCustomerResourceType = new ResourceType(typeof(DerivedCustomer), ResourceTypeKind.EntityType, this.customerResourceType, "Fake", "DerivedCustomer", false);

            this.weaklyBackedDerivedType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, derivedCustomerResourceType, "Fake", "WeaklyBackedCustomer", false)
            {
                CanReflectOnInstanceType = false
            };
            var nameResourceProperty = new ResourceProperty("Name", ResourcePropertyKind.Key | ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(string)));

            this.customerResourceType.AddProperty(nameResourceProperty);
            var addressResourceType     = new ResourceType(typeof(Address), ResourceTypeKind.ComplexType, null, "Fake", "Address", false);
            var addressResourceProperty = new ResourceProperty("Address", ResourcePropertyKind.ComplexType, addressResourceType);

            this.customerResourceType.AddProperty(addressResourceProperty);

            var namesResourceProperty = new ResourceProperty("Names", ResourcePropertyKind.Collection, ResourceType.GetCollectionResourceType(ResourceType.GetPrimitiveResourceType(typeof(string))));

            this.customerResourceType.AddProperty(namesResourceProperty);
            var addressesResourceProperty = new ResourceProperty("Addresses", ResourcePropertyKind.Collection, ResourceType.GetCollectionResourceType(addressResourceType));

            this.customerResourceType.AddProperty(addressesResourceProperty);

            var bestFriendResourceProperty = new ResourceProperty("BestFriend", ResourcePropertyKind.ResourceReference, this.customerResourceType);

            this.customerResourceType.AddProperty(bestFriendResourceProperty);
            var otherFriendsResourceProperty = new ResourceProperty("OtherFriends", ResourcePropertyKind.ResourceSetReference, this.customerResourceType);

            this.customerResourceType.AddProperty(otherFriendsResourceProperty);

            this.weaklyBackedResourceProperty = new ResourceProperty("WeaklyBacked", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(string)))
            {
                CanReflectOnInstanceTypeProperty = false
            };

            var guid1ResourceProperty         = new ResourceProperty("Guid1", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(Guid)));
            var guid2ResourceProperty         = new ResourceProperty("Guid2", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(Guid)));
            var nullableGuid1ResourceProperty = new ResourceProperty("NullableGuid1", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(Guid?)));
            var nullableGuid2ResourceProperty = new ResourceProperty("NullableGuid2", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(Guid?)));

            this.customerResourceType.AddProperty(guid1ResourceProperty);
            this.customerResourceType.AddProperty(guid2ResourceProperty);
            this.customerResourceType.AddProperty(nullableGuid1ResourceProperty);
            this.customerResourceType.AddProperty(nullableGuid2ResourceProperty);

            var resourceSet = new ResourceSet("Customers", this.customerResourceType);

            resourceSet.SetReadOnly();
            var resourceSetWrapper = ResourceSetWrapper.CreateForTests(resourceSet, EntitySetRights.All);

            this.model = new EdmModel();

            this.customerEdmType = new MetadataProviderEdmEntityType("Fake", this.customerResourceType, null, false, true, false, t => {});
            this.model.AddElement(this.customerEdmType);

            this.derivedCustomerEdmType = new MetadataProviderEdmEntityType("Fake", derivedCustomerResourceType, this.customerEdmType, false, false, false, t => { });
            this.model.AddElement(this.derivedCustomerEdmType);

            this.weaklyBackedCustomerEdmType = new MetadataProviderEdmEntityType("Fake", weaklyBackedDerivedType, this.derivedCustomerEdmType, false, false, false, t => { });
            this.model.AddElement(this.weaklyBackedCustomerEdmType);

            this.nameProperty = new MetadataProviderEdmStructuralProperty(this.customerEdmType, nameResourceProperty, EdmCoreModel.Instance.GetString(true), null, EdmConcurrencyMode.None);
            this.customerEdmType.AddProperty(this.nameProperty);

            var addressEdmType = new MetadataProviderEdmComplexType("Fake", addressResourceType, null, false, false, t => {});

            this.model.AddElement(addressEdmType);

            this.addressProperty = new MetadataProviderEdmStructuralProperty(this.customerEdmType, addressResourceProperty, new EdmComplexTypeReference(addressEdmType, true), null, EdmConcurrencyMode.None);
            this.customerEdmType.AddProperty(this.addressProperty);

            this.namesProperty = new MetadataProviderEdmStructuralProperty(this.customerEdmType, namesResourceProperty, new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetString(false))), null, EdmConcurrencyMode.None);
            this.customerEdmType.AddProperty(this.namesProperty);

            this.addressesProperty = new MetadataProviderEdmStructuralProperty(this.customerEdmType, addressesResourceProperty, new EdmCollectionTypeReference(new EdmCollectionType(new EdmComplexTypeReference(addressEdmType, false))), null, EdmConcurrencyMode.None);
            this.customerEdmType.AddProperty(this.addressesProperty);

            this.bestFriendNavigation = new MetadataProviderEdmNavigationProperty(this.customerEdmType, bestFriendResourceProperty, new EdmEntityTypeReference(this.customerEdmType, true));
            this.customerEdmType.AddProperty(this.bestFriendNavigation);

            this.otherFriendsNavigation = new MetadataProviderEdmNavigationProperty(this.customerEdmType, otherFriendsResourceProperty, new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(this.customerEdmType, true))));
            this.customerEdmType.AddProperty(this.otherFriendsNavigation);

            this.weaklyBackedProperty = new MetadataProviderEdmStructuralProperty(this.customerEdmType, this.weaklyBackedResourceProperty, EdmCoreModel.Instance.GetString(true), null, EdmConcurrencyMode.None);
            this.customerEdmType.AddProperty(this.weaklyBackedProperty);

            var guid1EdmProperty = new MetadataProviderEdmStructuralProperty(this.customerEdmType, guid1ResourceProperty, EdmCoreModel.Instance.GetGuid(false), null, EdmConcurrencyMode.None);

            this.customerEdmType.AddProperty(guid1EdmProperty);
            var guid2EdmProperty = new MetadataProviderEdmStructuralProperty(this.customerEdmType, guid2ResourceProperty, EdmCoreModel.Instance.GetGuid(false), null, EdmConcurrencyMode.None);

            this.customerEdmType.AddProperty(guid2EdmProperty);
            var nullableGuid1EdmProperty = new MetadataProviderEdmStructuralProperty(this.customerEdmType, nullableGuid1ResourceProperty, EdmCoreModel.Instance.GetGuid(true), null, EdmConcurrencyMode.None);

            this.customerEdmType.AddProperty(nullableGuid1EdmProperty);
            var nullableGuid2EdmProperty = new MetadataProviderEdmStructuralProperty(this.customerEdmType, nullableGuid2ResourceProperty, EdmCoreModel.Instance.GetGuid(true), null, EdmConcurrencyMode.None);

            this.customerEdmType.AddProperty(nullableGuid2EdmProperty);

            this.entitySet = new EdmEntitySetWithResourceSet(new EdmEntityContainer("Fake", "Container"), resourceSetWrapper, this.customerEdmType);
            ((EdmEntitySet)this.entitySet).AddNavigationTarget(this.bestFriendNavigation, this.entitySet);
            ((EdmEntitySet)this.entitySet).AddNavigationTarget(this.otherFriendsNavigation, this.entitySet);

            this.model.SetAnnotationValue(this.customerEdmType, this.customerResourceType);
            this.model.SetAnnotationValue(this.derivedCustomerEdmType, derivedCustomerResourceType);
            this.model.SetAnnotationValue(this.weaklyBackedCustomerEdmType, this.weaklyBackedDerivedType);
            this.model.SetAnnotationValue(this.nameProperty, nameResourceProperty);
            this.model.SetAnnotationValue(addressEdmType, addressResourceType);
            this.model.SetAnnotationValue(this.addressProperty, addressResourceProperty);
            this.model.SetAnnotationValue(this.namesProperty, namesResourceProperty);
            this.model.SetAnnotationValue(this.addressesProperty, addressesResourceProperty);
            this.model.SetAnnotationValue(this.bestFriendNavigation, bestFriendResourceProperty);
            this.model.SetAnnotationValue(this.otherFriendsNavigation, otherFriendsResourceProperty);
            this.model.SetAnnotationValue(this.weaklyBackedProperty, this.weaklyBackedResourceProperty);
            this.model.SetAnnotationValue(this.entitySet, resourceSetWrapper);
            this.model.SetAnnotationValue(guid1EdmProperty, guid1ResourceProperty);
            this.model.SetAnnotationValue(guid2EdmProperty, guid2ResourceProperty);
            this.model.SetAnnotationValue(nullableGuid1EdmProperty, nullableGuid1ResourceProperty);
            this.model.SetAnnotationValue(nullableGuid2EdmProperty, nullableGuid2ResourceProperty);

            this.testSubject = this.CreateTestSubject();
        }
Ejemplo n.º 14
-1
        /// <summary>
        /// Apply orderby to the given resouce expression
        /// </summary>
        /// <param name="rootExpression"></param>
        /// <param name="entityInstanceType"></param>
        /// <param name="uriParser"></param>
        /// <param name="orderByClause"></param>
        /// <returns></returns>
        public static Expression ApplyOrderBy(this Expression rootExpression, Type entityInstanceType, ODataUriParser uriParser, OrderByClause orderByClause)
        {
            ParameterExpression parameter = Expression.Parameter(entityInstanceType, "it");
            NodeToExpressionTranslator nodeToExpressionTranslator = new NodeToExpressionTranslator()
            {
                ImplicitVariableParameterExpression = parameter,
                UriParser = uriParser,
            };

            Expression orderByNodeExpression = nodeToExpressionTranslator.TranslateNode(orderByClause.Expression);

            var keyType = EdmClrTypeUtils.GetInstanceType(orderByClause.Expression.TypeReference);

            if (orderByClause.Expression.TypeReference.IsNullable && keyType.IsValueType)
            {
                keyType = typeof(Nullable<>).MakeGenericType(keyType);
            }

            var method = orderByClause.Direction == OrderByDirection.Ascending ? "OrderBy" : "OrderByDescending";
            //OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
            var expression = Expression.Call(
                typeof(Enumerable),
                method,
                new Type[] { entityInstanceType, keyType },
                rootExpression,
                Expression.Lambda(orderByNodeExpression, parameter)) as Expression;
            var thenBy = orderByClause.ThenBy;
            while (null != thenBy)
            {
                expression = expression.ApplyThenBy(entityInstanceType, uriParser, thenBy);
                thenBy = thenBy.ThenBy;
            }
            return expression;
        }