private void GenerateQueryResult() { if (this.description.CountOption == RequestQueryCountOption.ValueOnly) { this.description.VerifyProtocolVersion(RequestDescription.Version2Dot0, this.service); this.description.VerifyRequestVersion(RequestDescription.Version2Dot0, this.service); this.description.VerifyAndRaiseResponseVersion(RequestDescription.Version2Dot0, this.service); this.queryExpression = this.queryExpression.QueryableLongCount(); } else if (this.rootProjectionNode != null) { IExpandProvider service = this.service.Provider.GetService <IExpandProvider>(); if (service != null) { if (this.IsStandardPaged) { throw new DataServiceException(500, System.Data.Services.Strings.DataService_SDP_TopLevelPagedResultWithOldExpandProvider); } if (this.rootProjectionNode.ProjectionsSpecified) { throw new DataServiceException(500, System.Data.Services.Strings.DataService_Projections_ProjectionsWithOldExpandProvider); } if (this.rootProjectionNode.ExpansionOnDerivedTypesSpecified) { throw new DataServiceException(500, System.Data.Services.Strings.DataService_DerivedExpansions_OldExpandProvider); } this.ProcessOrderBy(); this.ProcessSkipAndTop(); this.queryExpression = Expression.Call(Expression.Constant(service), ApplyExpansionsMethodInfo, this.queryExpression, Expression.Constant(this.rootProjectionNode.ExpandPaths)); this.rootProjectionNode.UseExpandPathsForSerialization = true; } else { IProjectionProvider projectionProvider = this.service.Provider.ProjectionProvider; if (projectionProvider == null) { projectionProvider = new BasicExpandProvider(this.service.Provider, false, true); } this.queryExpression = Expression.Call(null, DataServiceExecutionProviderMethods.ApplyProjectionsMethodInfo, Expression.Constant(projectionProvider, typeof(object)), this.queryExpression, Expression.Constant(this.rootProjectionNode, typeof(object))); } } else if (!string.IsNullOrEmpty(this.service.OperationContext.Host.GetQueryStringItem("$expand"))) { this.ProjectSkipTokenForNonExpand(); this.ProcessOrderBy(); this.ProcessSkipAndTop(); } }
private void GenerateQueryResult() { if (this.description.CountOption == RequestQueryCountOption.ValueOnly) { this.description.VerifyProtocolVersion(RequestDescription.Version2Dot0, this.service); this.description.VerifyRequestVersion(RequestDescription.Version2Dot0, this.service); this.description.VerifyAndRaiseResponseVersion(RequestDescription.Version2Dot0, this.service); this.queryExpression = this.queryExpression.QueryableLongCount(); } else if (this.rootProjectionNode != null) { IExpandProvider service = this.service.Provider.GetService<IExpandProvider>(); if (service != null) { if (this.IsStandardPaged) { throw new DataServiceException(500, System.Data.Services.Strings.DataService_SDP_TopLevelPagedResultWithOldExpandProvider); } if (this.rootProjectionNode.ProjectionsSpecified) { throw new DataServiceException(500, System.Data.Services.Strings.DataService_Projections_ProjectionsWithOldExpandProvider); } if (this.rootProjectionNode.ExpansionOnDerivedTypesSpecified) { throw new DataServiceException(500, System.Data.Services.Strings.DataService_DerivedExpansions_OldExpandProvider); } this.ProcessOrderBy(); this.ProcessSkipAndTop(); this.queryExpression = Expression.Call(Expression.Constant(service), ApplyExpansionsMethodInfo, this.queryExpression, Expression.Constant(this.rootProjectionNode.ExpandPaths)); this.rootProjectionNode.UseExpandPathsForSerialization = true; } else { IProjectionProvider projectionProvider = this.service.Provider.ProjectionProvider; if (projectionProvider == null) { projectionProvider = new BasicExpandProvider(this.service.Provider, false, true); } this.queryExpression = Expression.Call(null, DataServiceExecutionProviderMethods.ApplyProjectionsMethodInfo, Expression.Constant(projectionProvider, typeof(object)), this.queryExpression, Expression.Constant(this.rootProjectionNode, typeof(object))); } } else if (!string.IsNullOrEmpty(this.service.OperationContext.Host.GetQueryStringItem("$expand"))) { this.ProjectSkipTokenForNonExpand(); this.ProcessOrderBy(); this.ProcessSkipAndTop(); } }
private void GenerateQueryResult() { if (this.description.CountOption == RequestQueryCountOption.CountSegment) { // set query result to Count this.queryExpression = this.queryExpression.QueryableLongCount(); } else if (this.rootProjectionNode != null) { #pragma warning disable 618 // Disable "obsolete" warning for the IExpandProvider interface. Used for backwards compatibilty. IExpandProvider expandProvider = this.service.Provider.GetService<IExpandProvider>(); #pragma warning restore 618 if (expandProvider != null) { // If top level result is paged, then we can not perform the operation since that would require // passing in the ordering expressions for $skiptoken generation for top level results which // the IExpandProvider interface does not support and thus we would get wrong results if (this.IsStandardPaged) { throw new DataServiceException(500, Strings.DataService_SDP_TopLevelPagedResultWithOldExpandProvider); } // If there's projection we can't perform the operation since that would require // passing the projection info into the IExpandProvider, which it doesn't support // and thus would not perform the projection. if (this.rootProjectionNode.ProjectionsSpecified) { throw new DataServiceException(500, Strings.DataService_Projections_ProjectionsWithOldExpandProvider); } if (this.rootProjectionNode.ExpansionOnDerivedTypesSpecified) { throw new DataServiceException(500, Strings.DataService_DerivedExpansions_OldExpandProvider); } // V1 behaviour of expand in this case, although this is semantically incorrect, since we are doing // a select after orderby and skip top, which could mess up the results, assuming here that count // has already been processed this.ProcessOrderBy(); this.ProcessSkipAndTop(); this.queryExpression = Expression.Call( Expression.Constant(expandProvider), RequestQueryProcessor.ApplyExpansionsMethodInfo, this.queryExpression, Expression.Constant(this.rootProjectionNode.ExpandPaths)); // We need to mark the ExpandPaths as "possibly modified" and make serializer use those instead. this.rootProjectionNode.UseExpandPathsForSerialization = true; } else { IProjectionProvider projectionProvider = this.service.Provider.ProjectionProvider; // We already have the parameter information // * Ordering expressions through ObtainOrderingExpressions // * Skip & Top through ObtainSkipTopCounts if (projectionProvider == null) { Debug.Assert(!this.service.Provider.HasReflectionOrEFProviderQueryBehavior, "Reflection and EF Providers should implement the IProjectionProvider interface."); // We are to run a query against IDSQP. Since the IProjectionProvider interface is not public // the provider will have to be able to handle queries generated by our BasicExpandProvider // so we should make only minimalistic assumptions about the provider's abilities. // In here we will assume that: // - the provider doesn't expand on demand, that is we need to generate projections for all expansions in the query // - the provider requires correct casting to "System.Object" when we assign a value to a property of type "System.Object" // A side effect of these assumptions is that if the provider just propagates the calls (with small modifications) to Linq to Objects // the query should just work (nice property, as this might be rather common). projectionProvider = new BasicExpandProvider(this.service.Provider, false, true); } this.queryExpression = Expression.Call( null, DataServiceExecutionProviderMethods.ApplyProjectionsMethodInfo, Expression.Constant(projectionProvider, typeof(object)), this.queryExpression, Expression.Constant(this.rootProjectionNode, typeof(object))); } } else { // Special case where although there were expand expressions, they were ignored because they did not refer to entity sets if (!String.IsNullOrEmpty(this.service.OperationContext.RequestMessage.GetQueryStringItem(XmlConstants.HttpQueryStringExpand))) { this.ProjectSkipTokenForNonExpand(); this.ProcessOrderBy(); this.ProcessSkipAndTop(); } } }