/// <summary> /// Constructor. /// </summary> /// <param name="queryProvider">The query provider</param> /// <param name="model">The model</param> public PathSegmentToExpressionTranslator(IODataDataSource dataSource, QueryContext queryContext, IEdmModel model) { this.dataSource = dataSource; this.queryContext = queryContext; this.model = model; this.ResultExpression = NullLiteralExpression; }
/// <summary> /// Create a RequestHandler on current context. /// </summary> /// <param name="httpMethod"></param> protected RequestHandler(HttpMethod httpMethod, IODataDataSource dataSource) { this.HttpMethod = httpMethod; this.RequestUri = Utility.RebuildUri(OperationContext.Current.RequestContext.RequestMessage.Properties.Via); this.DataSource = dataSource; this.RequestAcceptHeader = WebOperationContext.Current.IncomingRequest.Accept; this.RequestHeaders = WebOperationContext.Current.IncomingRequest.Headers.ToDictionary(); this.ServiceRootUri = Utility.RebuildUri(new Uri(OperationContext.Current.Host.BaseAddresses.First().AbsoluteUri.TrimEnd('/') + "/")); this.QueryContext = new QueryContext(this.ServiceRootUri, this.RequestUri, this.DataSource.Model); string preference = this.RequestHeaders.ContainsKey(ServiceConstants.HttpHeaders.Prefer) ? this.RequestHeaders[ServiceConstants.HttpHeaders.Prefer] : string.Empty; this.PreferenceContext = new PreferenceContext(preference); }
/// <summary> /// Resolves the parsed URI against the data store. /// </summary> /// <param name="model">The data store model.</param> /// <param name="dataContext">The data access context.</param> /// <param name="level">The level of segment need to be translated, the default value is -1 means translate all.</param> /// <returns>The results of querying the data store.</returns> public object ResolveQuery(IODataDataSource dataSource, int level = -1) { var testExpressionVisitor = new PathSegmentToExpressionTranslator(dataSource, this, this.Model) { ActionInvokeParameters = this.ActionInvokeParameters }; // build linq expression from ODataPath and execute the expression Expression boundExpression = Expression.Constant(null); int levelToTranslate = level == -1 ? this.QueryPath.Count - 1 : level; for (int i = 0; i <= levelToTranslate; ++i) { boundExpression = this.QueryPath.ElementAt(i).TranslateWith(testExpressionVisitor); } //Handle Action without return type var methodCallExpression = boundExpression as MethodCallExpression; if (methodCallExpression != null && methodCallExpression.Method.ReturnType == typeof(void)) { Expression <Action> actionLambda = Expression.Lambda <Action>(boundExpression); actionLambda.Compile()(); return(null); } if (this.QueryPath.LastSegment is NavigationPropertyLinkSegment && this.QueryEntityIdSegment != null) { // We assume the $id always finish with the keysegment, and consistence with the base path. ODataUriParser uriParser = new ODataUriParser(this.Model, ServiceConstants.ServiceBaseUri, this.QueryEntityIdSegment.Id); boundExpression = uriParser.ParsePath().LastSegment.TranslateWith(testExpressionVisitor); } // handle $filter query option if (this.QueryFilterClause != null) { boundExpression = boundExpression.ApplyFilter(GetElementTypeForOption(ServiceConstants.QueryOption_Filter), this.UriParser, this.QueryFilterClause); } //handle $search query option if (this.QuerySearchClause != null) { boundExpression = boundExpression.ApplySearch(GetElementTypeForOption(ServiceConstants.QueryOption_Search), this.UriParser, this.QuerySearchClause); } //handle $orderby query option if (this.QueryOrderByClause != null) { boundExpression = boundExpression.ApplyOrderBy(GetElementTypeForOption(ServiceConstants.QueryOption_OrderBy), this.UriParser, this.QueryOrderByClause); } //handle $skip query option if (this.SkipOption != null) { boundExpression = boundExpression.ApplySkip(GetElementTypeForOption(ServiceConstants.QueryOption_Skip), this.SkipOption.Value); } //handle $top query option if (this.TopOption != null) { boundExpression = boundExpression.ApplyTop(GetElementTypeForOption(ServiceConstants.QueryOption_Top), this.TopOption.Value); } boundExpression = Expression.Convert(boundExpression, typeof(object)); Expression <Func <object> > lambda = Expression.Lambda <Func <object> >(boundExpression); Func <object> compiled = lambda.Compile(); var result = default(object); try { result = compiled(); } catch (NullReferenceException) { // Currently we assume the NRE will lead to NotFound. throw Utility.BuildException(HttpStatusCode.NotFound); } return(ProcessQueryResult(result)); }
public static object GetRootQuery(IODataDataSource dataSource, IEdmNavigationSource navigationSource) { return(dataSource.GetType().GetProperty(navigationSource.Name).GetValue(dataSource, null)); }
public ODataSimplifiedRequestHandler(HttpMethod httpMethod, IODataDataSource dataSource) : base(httpMethod, dataSource) { }
public RootRequestHandler(HttpMethod httpMethod, IODataDataSource dataSource) : base(httpMethod, dataSource) { }
public static object GetRootQuery(IODataDataSource dataSource, IEdmNavigationSource navigationSource) { return dataSource.GetType().GetProperty(navigationSource.Name).GetValue(dataSource, null); }
public PluggableFormatRequestHandler(HttpMethod httpMethod, IODataDataSource dataSource) : base(httpMethod, dataSource) { }
/// <summary> /// Resolves the parsed URI against the data store. /// </summary> /// <param name="model">The data store model.</param> /// <param name="dataContext">The data access context.</param> /// <param name="level">The level of segment need to be translated, the default value is -1 means translate all.</param> /// <returns>The results of querying the data store.</returns> public object ResolveQuery(IODataDataSource dataSource, int level = -1) { var testExpressionVisitor = new PathSegmentToExpressionTranslator(dataSource, this, this.Model) { ActionInvokeParameters = this.ActionInvokeParameters }; // build linq expression from ODataPath and execute the expression Expression boundExpression = Expression.Constant(null); int levelToTranslate = level == -1 ? this.QueryPath.Count - 1 : level; for (int i = 0; i <= levelToTranslate; ++i) { boundExpression = this.QueryPath.ElementAt(i).TranslateWith(testExpressionVisitor); } //Handle Action without return type var methodCallExpression = boundExpression as MethodCallExpression; if (methodCallExpression != null && methodCallExpression.Method.ReturnType == typeof(void)) { Expression<Action> actionLambda = Expression.Lambda<Action>(boundExpression); actionLambda.Compile()(); return null; } if (this.QueryPath.LastSegment is NavigationPropertyLinkSegment && this.QueryEntityIdSegment != null) { // We assume the $id always finish with the keysegment, and consistence with the base path. ODataUriParser uriParser = new ODataUriParser(this.Model, ServiceConstants.ServiceBaseUri, this.QueryEntityIdSegment.Id); boundExpression = uriParser.ParsePath().LastSegment.TranslateWith(testExpressionVisitor); } // handle $filter query option if (this.QueryFilterClause != null) { boundExpression = boundExpression.ApplyFilter(GetElementTypeForOption(ServiceConstants.QueryOption_Filter), this.UriParser, this.QueryFilterClause); } //handle $search query option if (this.QuerySearchClause != null) { boundExpression = boundExpression.ApplySearch(GetElementTypeForOption(ServiceConstants.QueryOption_Search), this.UriParser, this.QuerySearchClause); } //handle $orderby query option if (this.QueryOrderByClause != null) { boundExpression = boundExpression.ApplyOrderBy(GetElementTypeForOption(ServiceConstants.QueryOption_OrderBy), this.UriParser, this.QueryOrderByClause); } //handle $skip query option if (this.SkipOption != null) { boundExpression = boundExpression.ApplySkip(GetElementTypeForOption(ServiceConstants.QueryOption_Skip), this.SkipOption.Value); } //handle $top query option if (this.TopOption != null) { boundExpression = boundExpression.ApplyTop(GetElementTypeForOption(ServiceConstants.QueryOption_Top), this.TopOption.Value); } boundExpression = Expression.Convert(boundExpression, typeof(object)); Expression<Func<object>> lambda = Expression.Lambda<Func<object>>(boundExpression); Func<object> compiled = lambda.Compile(); var result = default(object); try { result = compiled(); } catch (NullReferenceException) { // Currently we assume the NRE will lead to NotFound. throw Utility.BuildException(HttpStatusCode.NotFound); } return ProcessQueryResult(result); }