/// <summary> /// Returns true if the specified operation should be inferred as an invoke operation. /// </summary> /// <param name="operation">The operation to inspect.</param> /// <returns>True if the operation is an invoke operation, false otherwise.</returns> private static bool IsInvokeOperation(DomainOperationEntry operation) { foreach (DomainOperationParameter parameter in operation.Parameters) { // All parameters must be supported Types. // If there are any entity type parameters, then it's not an invoke operation that follows the // convention. The developer will need to explicitly mark the operation with InvokeAttribute. if (!IsPredefinedOrComplexType(parameter.ParameterType)) { return(false); } } // We'll match service operations by convention only if they are void returning, // return a simple or complex type, or a collection thereof. // All methods not matching this convention must be explicitly attributed (e.g. those returning entities). if (operation.ReturnType == typeof(void) || IsPredefinedOrComplexType(operation.ReturnType)) { return(true); } return(false); }
/// <summary> /// If the query operation has a result limit, this operation will compose Take(limit) on top /// of the specified results. /// </summary> /// <param name="results">The results that may need to be limited.</param> /// <param name="queryOperation">The query operation that was invoked to get the results.</param> /// <param name="limitedResults">The limited results. It will be <value>null</value> if there is no result limit.</param> /// <returns>True if a limited result query is returned, false otherwise.</returns> internal static bool TryComposeWithLimit(IEnumerable results, DomainOperationEntry queryOperation, out IEnumerable limitedResults) { int limit = ((QueryAttribute)queryOperation.OperationAttribute).ResultLimit; if (limit > 0) { IQueryable queryableResult = results.AsQueryable(); // Compose Take(limit) over the results. IQueryable limitQuery = Array.CreateInstance(queryOperation.AssociatedType, 0).AsQueryable(); limitQuery = limitQuery.Provider.CreateQuery( Expression.Call( typeof(Queryable), "Take", new Type[] { limitQuery.ElementType }, limitQuery.Expression, Expression.Constant(limit))); limitedResults = QueryComposer.Compose(queryableResult, limitQuery); return(true); } limitedResults = null; return(false); }
/// <summary> /// Initializes a new instance of the <see cref="QueryDescription"/> class with the specified /// <see cref="DomainOperationEntry"/>, parameter values, flag indicating whether /// to evaluate and include total entity count in the result and (optional) query to compose over /// the results. /// </summary> /// <param name="domainOperationEntry">The query operation to be processed</param> /// <param name="parameterValues">Parameter values for the method if it requires any</param> /// <param name="includeTotalCount">Flag to indicate that total entity count is required</param> /// <param name="query">The query to compose over the results</param> public QueryDescription(DomainOperationEntry domainOperationEntry, object[] parameterValues, bool includeTotalCount, IQueryable query) : this(domainOperationEntry, parameterValues) { this._query = query; this._includeTotalCount = includeTotalCount; }
/// <summary> /// Returns true if the specified operation should be inferred as an /// IEnumerable or singleton returning query method. Also checks if the /// base element type or the type of the singleton is a valid entity type. /// </summary> /// <param name="operation">The operation to inspect.</param> /// <returns>True if the operation is a query method, false otherwise.</returns> private bool IsQueryMethod(DomainOperationEntry operation) { Type elementType = TypeUtility.GetElementType(operation.ReturnType); return(this.IsEntityType(elementType)); }