/// <summary> /// Create a new ODataUri. This contains the semantic meaning of the /// entire uri. /// </summary> /// <param name="parameterAliasValueAccessor">The ParameterAliasValueAccessor.</param> /// <param name="path">The top level path for this uri.</param> /// <param name="customQueryOptions">Any custom query options for this uri. Can be null.</param> /// <param name="selectAndExpand">Any $select or $expand option for this uri. Can be null.</param> /// <param name="filter">Any $filter option for this uri. Can be null.</param> /// <param name="orderby">Any $orderby option for this uri. Can be null</param> /// <param name="search">Any $search option for this uri. Can be null</param> /// <param name="apply">Any $apply option for this uri. Can be null</param> /// <param name="skip">Any $skip option for this uri. Can be null.</param> /// <param name="top">Any $top option for this uri. Can be null.</param> /// <param name="queryCount">Any query $count option for this uri. Can be null.</param> internal ODataUri( ParameterAliasValueAccessor parameterAliasValueAccessor, ODataPath path, IEnumerable<QueryNode> customQueryOptions, SelectExpandClause selectAndExpand, FilterClause filter, OrderByClause orderby, SearchClause search, ApplyClause apply, long? skip, long? top, bool? queryCount) { this.ParameterAliasValueAccessor = parameterAliasValueAccessor; this.Path = path; this.CustomQueryOptions = new ReadOnlyCollection<QueryNode>(customQueryOptions.ToList()); this.SelectAndExpand = selectAndExpand; this.Filter = filter; this.OrderBy = orderby; this.Search = search; this.Apply = apply; this.Skip = skip; this.Top = top; this.QueryCount = queryCount; }
/// <summary> /// Binds the given filter token. /// </summary> /// <param name="filter">The filter token to bind.</param> /// <returns>A FilterNode with the given path linked to it (if provided).</returns> internal FilterClause BindFilter(QueryToken filter) { ExceptionUtils.CheckArgumentNotNull(filter, "filter"); QueryNode expressionNode = this.bindMethod(filter); SingleValueNode expressionResultNode = expressionNode as SingleValueNode; if (expressionResultNode == null || (expressionResultNode.TypeReference != null && !expressionResultNode.TypeReference.IsODataPrimitiveTypeKind())) { throw new ODataException(ODataErrorStrings.MetadataBinder_FilterExpressionNotSingleValue); } // The type may be null here if the query statically represents the null literal or an open property. IEdmTypeReference expressionResultType = expressionResultNode.TypeReference; if (expressionResultType != null) { IEdmPrimitiveTypeReference primitiveExpressionResultType = expressionResultType.AsPrimitiveOrNull(); if (primitiveExpressionResultType == null || primitiveExpressionResultType.PrimitiveKind() != EdmPrimitiveTypeKind.Boolean) { throw new ODataException(ODataErrorStrings.MetadataBinder_FilterExpressionNotSingleValue); } } FilterClause filterNode = new FilterClause(expressionResultNode, this.state.ImplicitRangeVariable); return filterNode; }
public static string BindFilterQueryOption(FilterClause filterClause, IEdmModel model) { if (filterClause == null || model == null) return string.Empty; SQLFilterBinder binder = new SQLFilterBinder(model); return binder.BindFilterClause(filterClause) + Environment.NewLine; }
public void FilterOptionSetCorrectly() { BinaryOperatorNode filterExpression = new BinaryOperatorNode(BinaryOperatorKind.Equal, new ConstantNode(1), new ConstantNode(1)); FilterClause filterClause = new FilterClause(filterExpression, new EntityRangeVariable(ExpressionConstants.It, HardCodedTestModel.GetPersonTypeReference(), HardCodedTestModel.GetPeopleSet())); ExpandedNavigationSelectItem expansion = new ExpandedNavigationSelectItem(new ODataExpandPath(new NavigationPropertySegment(ModelBuildingHelpers.BuildValidNavigationProperty(), null)), HardCodedTestModel.GetPeopleSet(), null, filterClause, null, null, null, null, null, null); expansion.FilterOption.Expression.ShouldBeBinaryOperatorNode(BinaryOperatorKind.Equal); expansion.FilterOption.Expression.As<BinaryOperatorNode>().Left.ShouldBeConstantQueryNode(1); expansion.FilterOption.Expression.As<BinaryOperatorNode>().Right.ShouldBeConstantQueryNode(1); }
public SqlFilterBinder(FilterClause filterClause) { if (filterClause != null) { //TODO: Resolver posteriormente de maneira mais elegante if (filterClause.Expression is BinaryOperatorNode) Query = new BinaryOperatorResolver(filterClause.Expression as BinaryOperatorNode); else if (filterClause.Expression is SingleValueFunctionCallNode) Query = new SingleValueFunctionResolver(filterClause.Expression as SingleValueFunctionCallNode); } }
/// <summary> /// Create an expand item, using a navigationProperty, its entity set, and any expand options. /// </summary> /// <param name="pathToNavigationProperty">the path to the navigation property for this expand item, including any type segments</param> /// <param name="navigationSource">the navigation source for this expand level.</param> /// <param name="selectAndExpand">This level select and any sub expands for this expand item.</param> /// <param name="filterOption">A filter clause for this expand (can be null)</param> /// <param name="orderByOption">An Orderby clause for this expand (can be null)</param> /// <param name="topOption">A top clause for this expand (can be null)</param> /// <param name="skipOption">A skip clause for this expand (can be null)</param> /// <param name="countOption">An query count clause for this expand (can be null)</param> /// <param name="searchOption">An levels clause for this expand (can be null)</param> /// <param name="levelsOption">An levels clause for this expand (can be null)</param> /// <exception cref="System.ArgumentNullException">Throws if input pathToNavigationProperty is null.</exception> public ExpandedNavigationSelectItem( ODataExpandPath pathToNavigationProperty, IEdmNavigationSource navigationSource, SelectExpandClause selectAndExpand, FilterClause filterOption, OrderByClause orderByOption, long?topOption, long?skipOption, bool?countOption, SearchClause searchOption, LevelsClause levelsOption) : base(pathToNavigationProperty, navigationSource, filterOption, orderByOption, topOption, skipOption, countOption, searchOption) { ExceptionUtils.CheckArgumentNotNull(pathToNavigationProperty, "pathToNavigationProperty"); this.SelectAndExpand = selectAndExpand; this.LevelsOption = levelsOption; }
/// <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)); }
/// <summary> /// Create an expand item, using a navigationProperty, its entity set, and any expand options. /// </summary> /// <param name="pathToNavigationProperty">the path to the navigation property for this expand item, including any type segments</param> /// <param name="navigationSource">the navigation source for this expand level.</param> /// <param name="filterOption">A filter clause for this expand (can be null)</param> /// <param name="orderByOption">An Orderby clause for this expand (can be null)</param> /// <param name="topOption">A top clause for this expand (can be null)</param> /// <param name="skipOption">A skip clause for this expand (can be null)</param> /// <param name="countOption">An query count clause for this expand (can be null)</param> /// <param name="searchOption">An levels clause for this expand (can be null)</param> /// <exception cref="System.ArgumentNullException">Throws if input pathToNavigationProperty is null.</exception> public ExpandedReferenceSelectItem( ODataExpandPath pathToNavigationProperty, IEdmNavigationSource navigationSource, FilterClause filterOption, OrderByClause orderByOption, long?topOption, long?skipOption, bool?countOption, SearchClause searchOption) { ExceptionUtils.CheckArgumentNotNull(pathToNavigationProperty, "pathToNavigationProperty"); this.PathToNavigationProperty = pathToNavigationProperty; this.NavigationSource = navigationSource; this.FilterOption = filterOption; this.OrderByOption = orderByOption; this.TopOption = topOption; this.SkipOption = skipOption; this.CountOption = countOption; this.SearchOption = searchOption; }
/// <summary> /// Parses a filter clause on the given full Uri, binding /// the text into semantic nodes using the constructed mode. /// </summary> /// <returns>A <see cref="FilterClause"/> representing the metadata bound filter expression.</returns> public FilterClause ParseFilter() { if (this.filterClause != null) { return this.filterClause; } string filterQuery; if (!this.TryGetQueryOption(UriQueryConstants.FilterQueryOption, out filterQuery) || string.IsNullOrEmpty(filterQuery) || this.targetEdmType == null) { return null; } this.filterClause = ParseFilterImplementation(filterQuery, this.Configuration, this.targetEdmType, this.targetNavigationSource); return this.filterClause; }
/// <summary> /// Compares Filter query nodes. /// </summary> /// <param name="left">Left side of comparison</param> /// <param name="right">Right side of comparison</param> /// <returns>True if equal, otherwise false</returns> public bool Compare(FilterClause left, FilterClause right) { if (left.ItemType != right.ItemType) return false; if (!this.Compare(left.Expression, right.Expression)) return false; if (!this.CompareParameters(left.RangeVariable, right.RangeVariable)) return false; return true; }
/// <summary> /// Create a FilterTransformationNode. /// </summary> /// <param name="filterClause">A <see cref="FilterClause"/> representing the metadata bound filter expression.</param> public FilterTransformationNode(FilterClause filterClause) { ExceptionUtils.CheckArgumentNotNull(filterClause, "filterClause"); this.filterClause = filterClause; }
protected string BindFilterClause(FilterClause filterClause) { return Bind(filterClause.Expression); }
public static void VerifyFilterClausesAreEqual(FilterClause expected, FilterClause actual, AssertionHandler assert) { VeryfyRangeVariablesAreEqual(expected.RangeVariable, actual.RangeVariable, assert); VerifyQueryNodesAreEqual(expected.Expression, actual.Expression, assert); }
public void FilterBinderTest() { IEdmModel model = QueryTestMetadata.BuildTestMetadata(this.PrimitiveTypeResolver, this.UntypedDataServiceProviderFactory); this.CombinatorialEngineProvider.RunCombinations( LiteralTestCases() .Concat(UnaryOperatorTestCases()) .Concat(BinaryOperatorTestCases()) .Concat(PropertyAccessTestCases(model)) .Concat(TopFilterExpressionTestCases(model)) .Concat(BuiltInStringFunctionCallTestCases(model)) .Concat(BuiltInDateTimeOffsetFunctionCallTestCases(model)) .Concat(BuiltInMathFunctionCallTestCases(model)), (testCase) => { string query = "/" + testCase.EntitySetName + "?$filter=" + testCase.Filter; ODataUri actual = QueryNodeUtils.BindQuery(query, model); // construct the expected filter node var entitySet = model.FindDeclaredEntitySet(testCase.EntitySetName); EntityCollectionNode entityCollectionNode = new EntitySetNode(entitySet); var expectedFilter = new FilterClause( testCase.ExpectedFilterCondition, new EntityRangeVariable(ExpressionConstants.It, entitySet.EntityType().ToTypeReference(false).AsEntity(), entityCollectionNode) ); QueryNodeUtils.VerifyFilterClausesAreEqual( expectedFilter, actual.Filter, this.Assert); }); }
/// <summary> /// Writes a test case for baselining. /// </summary> /// <param name="node">Node to write to string</param> /// <param name="originalOrderBy">Original $filter string.</param> /// <returns>String representation of the output from the URI Parser.</returns> internal static string GetTestCaseAndResultString(FilterClause node, string originalOrderBy) { return "$filter = " + originalOrderBy + "\n\n" + ToString(node); }
/// <summary> /// Writes filter clause to string. /// </summary> /// <param name="node">Node to write to string</param> /// <returns>String representation of node.</returns> public static string ToString(FilterClause node) { if (node != null) { string text = tabHelper.Prefix + "FilterQueryOption" + tabHelper.Indent(() => tabHelper.Prefix + "ItemType = " + node.ItemType + tabHelper.Prefix + "Parameter = " + ToStringParameter(node.RangeVariable) + tabHelper.Prefix + "Expression = " + ToString(node.Expression) ); return text; } return String.Empty; }