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); }
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()); }
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)); }