private TSelect ApplySelectExpand <TSelect>(TSelect entity, ODataQuerySettings settings)
        {
            var result = default(TSelect);

            SelectExpandClause      processedClause = this.SelectExpand.ProcessLevels();
            SelectExpandQueryOption newSelectExpand = new SelectExpandQueryOption(
                this.SelectExpand.RawSelect,
                this.SelectExpand.RawExpand,
                this.SelectExpand.Context,
                processedClause);

            ODataSettings qsettings = this.Context.RequestContainer.GetRequiredService <ODataSettings>();

            newSelectExpand.Validate(qsettings.ValidationSettings);

            var type = typeof(TSelect);

            if (type == typeof(IQueryable))
            {
                result = (TSelect)newSelectExpand.ApplyTo((IQueryable)entity, settings);
            }
            else if (type == typeof(object))
            {
                result = (TSelect)newSelectExpand.ApplyTo(entity, settings);
            }


            return(result);
        }
Beispiel #2
0
        public async Task SelectExpandQueryOption_NameAge()
        {
            var users   = GetUsers(20, 30);
            var context = GetQueryContext();

            var query    = new SelectExpandQueryOption("Name,Age", null, context);
            var settings = new ODataQuerySettings {
                HandleNullPropagation = HandleNullPropagationOption.True
            };
            var results = query.ApplyTo <UserProfile>(users, settings);

            Assert.AreEqual(10, await results.CountAsync());

            // Validate the properties got selected correctly.
            using (var u = users.GetAsyncEnumerator())
                using (var r = results.GetAsyncEnumerator())
                {
                    var token = CancellationToken.None;
                    while (await u.MoveNextAsync(token) && await r.MoveNextAsync(token))
                    {
                        var obj = JObject.FromObject(r.Current);
                        Assert.AreEqual(u.Current.Age, obj.Property("Age").Value.Value <int>());
                        Assert.AreEqual(u.Current.Name, obj.Property("Name").Value.Value <string>());
                    }
                }
        }
        public static IAsyncEnumerable <object> ApplyTo <T>(this SelectExpandQueryOption query, IAsyncEnumerable <T> source, ODataQuerySettings settings)
        {
            Type elementType = query.Context.ElementClrType;

            // Apply the operation on an empty enumerable to compile the filter expression.
            var emptySource = Array.CreateInstance(elementType, 0);
            var queryable   = query.ApplyTo(emptySource.AsQueryable(), settings);

            // Validate the queryable was processed as we expect.
            var expression = queryable.Expression as MethodCallExpression;

            Contract.Assert(expression != null);
            Contract.Assert(expression.Arguments.Count == 2);

            // Extract the lambda expression, so we can apply it to an async enumerable.
            var unaryExpression = expression.Arguments[1] as UnaryExpression;

            Contract.Assert(unaryExpression != null);
            var lambdaExpression = unaryExpression.Operand as LambdaExpression;

            Contract.Assert(lambdaExpression != null);

            // Compile the lambda expression into a delegate.
            var selector = lambdaExpression.Compile();

            // Pass the select delegate to the async where LINQ extension.
            MethodInfo selectMethod = ExpressionHelperMethods.AsyncSelectGeneric.MakeGenericMethod(elementType, lambdaExpression.ReturnType);

            return((IAsyncEnumerable <object>)selectMethod.Invoke(null, new object[] { source, selector }));
        }
        public async Task <IActionResult> OnContextDto(ODataQueryOptions <DeveloperDto> oDataQuery)
        {
            var edmModel            = EdmModelConfig.GetEdmModel();
            var edmNavigationSource = edmModel.FindDeclaredEntitySet(nameof(Developer));

            var context = new ODataQueryContext(edmModel, typeof(Developer), oDataQuery.Context.Path);
            var edmType = context.ElementType;

            var parameters = new Dictionary <string, string>();

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Filter))
            {
                parameters.Add("$filter", oDataQuery.RawValues.Filter);
            }

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Expand))
            {
                parameters.Add("$expand", oDataQuery.RawValues.Expand);
            }

            parameters.Add("$count", "true");

            var parser = new ODataQueryOptionParser(edmModel, edmType, edmNavigationSource, parameters);

            IQueryable <object> expandableQueryable = null;
            var queryable = (IQueryable <Developer>)_databaseContext.Developer;

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Filter))
            {
                var filter = new FilterQueryOption(oDataQuery.RawValues.Filter, context, parser);
                queryable = (IQueryable <Developer>)filter.ApplyTo(queryable, new ODataQuerySettings());
            }

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Expand))
            {
                var expand = new SelectExpandQueryOption(null, oDataQuery.RawValues.Expand, context, parser);
                expandableQueryable = (IQueryable <object>)expand.ApplyTo(queryable, new ODataQuerySettings());
            }

            IQueryable <object> queryToExecute = expandableQueryable ?? queryable;
            var records = await queryToExecute.ToListAsync();

            var count = await queryToExecute.CountAsync();

            var odataProperties = Request.ODataFeature();

            var response = new
            {
                Result     = MapDto(records),
                TotalCount = count,
                OData      = odataProperties
            };

            return(Ok(response));
        public IHttpActionResult Get(ODataQueryOptions <Product> query)
        {
            IEdmEntityType edmType = query.Context.ElementType as IEdmEntityType;
            IList <string> defaultSelects, defaultHiddens;

            Get(query.Context.Model, edmType, out defaultSelects, out defaultHiddens);

            var    queryNameValuePairs = query.Request.GetQueryNameValuePairs().ToDictionary(p => p.Key, p => p.Value);
            string selectValue;

            if (queryNameValuePairs.TryGetValue("$select", out selectValue))
            {
                foreach (var prop in defaultSelects)
                {
                    if (!selectValue.Contains(prop))
                    {
                        selectValue += ("," + prop);
                    }
                }
            }
            else
            {
                selectValue = string.Join(",", defaultSelects);
            }

            string expandValue;

            if (queryNameValuePairs.TryGetValue("$expand", out expandValue))
            {
            }
            queryNameValuePairs["$select"] = selectValue;

            IDictionary <string, string> options = new Dictionary <string, string>();

            options["$select"] = selectValue;
            if (expandValue != null)
            {
                options["$expand"] = expandValue;
            }


            ODataQueryOptionParser  parser       = new ODataQueryOptionParser(query.Context.Model, query.Context.ElementType, query.Context.NavigationSource, options);
            SelectExpandQueryOption selectExpand = new SelectExpandQueryOption(selectValue, expandValue, query.Context, parser);
            var a = selectExpand.SelectExpandClause;

            ODataQuerySettings settings = new ODataQuerySettings();

            var  ret  = selectExpand.ApplyTo(_products.AsQueryable(), settings);
            Type type = ret.GetType();

            return(Ok(ret, type));
            // return queryOptions.ApplyTo(_products.AsQueryable());
        }
Beispiel #6
0
        public void ApplyTo_OnSingleEntity_WithUnTypedContext_Throws_InvalidOperation()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataQueryContext context = new ODataQueryContext(model.Model, model.Customer);
            context.RequestContainer = new MockContainer();
            SelectExpandQueryOption selectExpand = new SelectExpandQueryOption(select: "ID", expand: null, context: context);
            object entity = new object();

            // Act & Assert
            ExceptionAssert.Throws<NotSupportedException>(() => selectExpand.ApplyTo(entity, new ODataQuerySettings()),
                "The query option is not bound to any CLR type. 'ApplyTo' is only supported with a query option bound to a CLR type.");
        }
        public async Task <IActionResult> OData(ODataQueryOptions <DeveloperDto> oDataQuery)
        {
            var edmModel     = EdmModelConfig.GetEdmModel();
            var edmEntitySet = edmModel.FindDeclaredEntitySet(nameof(Developer));

            var context = new ODataQueryContext(edmModel, typeof(Developer), oDataQuery.Context.Path);
            var edmType = context.ElementType;

            var parameters = new Dictionary <string, string>();

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Filter))
            {
                parameters.Add("$filter", oDataQuery.RawValues.Filter);
            }

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Expand))
            {
                parameters.Add("$expand", oDataQuery.RawValues.Expand);
            }

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.OrderBy))
            {
                parameters.Add("$orderby", oDataQuery.RawValues.OrderBy);
            }

            var parser = new ODataQueryOptionParser(edmModel, edmType, edmEntitySet, parameters);

            var queryable = (IQueryable <Developer>)_databaseContext.Developer;

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Filter))
            {
                var filter = new FilterQueryOption(oDataQuery.RawValues.Filter, context, parser);
                queryable = (IQueryable <Developer>)filter.ApplyTo(queryable, new ODataQuerySettings());
            }

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.OrderBy))
            {
                var orderBy = new OrderByQueryOption(oDataQuery.RawValues.OrderBy, context, parser);
                queryable = orderBy.ApplyTo(queryable, new ODataQuerySettings());
            }

            IQueryable <object> expandableQueryable = null;

            if (!string.IsNullOrWhiteSpace(oDataQuery.RawValues.Expand))
            {
                var expand = new SelectExpandQueryOption(null, oDataQuery.RawValues.Expand, context, parser);
                expandableQueryable = (IQueryable <object>)expand.ApplyTo(queryable, new ODataQuerySettings());
            }

            int pageIndex    = 1;
            var hasPageIndex = oDataQuery.Request.Query.TryGetValue("$pageindex", out StringValues pageIndexRaw);

            if (hasPageIndex)
            {
                var isTrue = int.TryParse(pageIndexRaw, out int _pageIndexRaw);
                pageIndex = (isTrue && _pageIndexRaw > 0) ? _pageIndexRaw : pageIndex;
            }

            int pageSize    = 10;
            var hasPageSize = oDataQuery.Request.Query.TryGetValue("$pagesize", out StringValues pageSizeRaw);

            if (hasPageSize)
            {
                var isTrue = int.TryParse(pageSizeRaw, out int _pageSizeRaw);
                pageSize = (isTrue && _pageSizeRaw > 0) ? _pageSizeRaw : pageSize;
            }

            IQueryable <object> queryToExecute = expandableQueryable ?? queryable;
            var records = await queryToExecute.Skip((pageIndex - 1) *pageSize).Take(pageSize).ToListAsync();

            var count = await queryToExecute.CountAsync();

            var pageList = new PageList <Developer>(MapDomain(records).ToList(), count, pageIndex, pageSize);
            var response = PageListDto <DeveloperDto> .Map(pageList, DeveloperDto.MapDomainToDto);

            return(Ok(response));
        }