Ejemplo n.º 1
0
        /// <summary>
        /// Invokes the select method and gets the result. Also handles auto paging and sorting when required.
        /// </summary>
        /// <param name="arguments">The DataSourceSelectArguments for the select operation.
        /// When applicable, this method sets the TotalRowCount out parameter in the arguments.
        /// </param>
        /// <returns>The return value from the select method.</returns>
        protected virtual object GetSelectMethodResult(DataSourceSelectArguments arguments)
        {
            if (SelectMethod.Length == 0)
            {
                throw new InvalidOperationException(SR.GetString(SR.ModelDataSourceView_SelectNotSupported));
            }

            DataSourceSelectResultProcessingOptions options = null;
            ModelDataSourceMethod method = EvaluateSelectMethodParameters(arguments, out options);
            ModelDataMethodResult result = InvokeMethod(method);

            return(ProcessSelectMethodResult(arguments, options, result));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Evaluates the select method parameters and also determines the options for processing select result like auto paging and sorting behavior.
        /// </summary>
        /// <param name="arguments">The DataSourceSelectArguments for the select operation.</param>
        /// <param name="selectResultProcessingOptions">The <see cref="System.Web.UI.WebControls.DataSourceSelectResultProcessingOptions"/> to use
        /// for processing the select result once select operation is complete. These options are determined in this method and later used
        /// by the method <see cref="System.Web.UI.WebControls.ModelDataSourceView.ProcessSelectMethodResult"/>.
        /// </param>
        /// <returns>A <see cref="System.Web.UI.WebControls.ModelDataSourceMethod"/> with the information required to invoke the select method.</returns>
        protected virtual ModelDataSourceMethod EvaluateSelectMethodParameters(DataSourceSelectArguments arguments, out DataSourceSelectResultProcessingOptions selectResultProcessingOptions)
        {
            ModelDataSourceMethod method;
            IOrderedDictionary    mergedParameters = MergeSelectParameters(arguments);

            // Resolve the method
            method = FindMethod(SelectMethod);

            Type selectMethodReturnType = method.MethodInfo.ReturnType;
            Type modelType = ModelType;

            if (modelType == null)
            {
                //When ModelType is not specified but SelectMethod returns IQueryable<T>, we treat T as model type for auto paging and sorting.
                //If the return type is something like CustomType<U,T> : IQueryable<T>, we should use T for paging and sorting, hence
                //we walk over the return type's generic arguments for a proper match.
                foreach (Type typeParameter in selectMethodReturnType.GetGenericArguments())
                {
                    if (typeof(IQueryable <>).MakeGenericType(typeParameter).IsAssignableFrom(selectMethodReturnType))
                    {
                        modelType = typeParameter;
                    }
                }
            }
            Type queryableModelType = (modelType != null) ? typeof(IQueryable <>).MakeGenericType(modelType) : null;

            //We do auto paging or auto sorting when the select method is returning an IQueryable and does not have parameters for paging or sorting.
            bool isReturningQueryable = queryableModelType != null && queryableModelType.IsAssignableFrom(selectMethodReturnType);

            bool autoPage = false;
            bool autoSort = false;

            if (arguments.StartRowIndex >= 0 && arguments.MaximumRows > 0)
            {
                autoPage = IsAutoPagingRequired(method.MethodInfo, isReturningQueryable);
            }

            if (!String.IsNullOrEmpty(arguments.SortExpression))
            {
                autoSort = IsAutoSortingRequired(method.MethodInfo, isReturningQueryable);
            }

            selectResultProcessingOptions = new DataSourceSelectResultProcessingOptions()
            {
                ModelType = modelType, AutoPage = autoPage, AutoSort = autoSort
            };
            EvaluateMethodParameters(DataSourceOperation.Select, method, mergedParameters);
            return(method);
        }
        /// <summary>
        /// This method performs operations on the select method result like auto paging and sorting if applicable.
        /// </summary>
        /// <param name="arguments">The DataSourceSelectArguments for the select operation.</param>
        /// <param name="selectResultProcessingOptions">The <see cref="System.Web.UI.WebControls.DataSourceSelectResultProcessingOptions"/> to use for processing the select result.
        /// These options are determined in an earlier call to <see cref="System.Web.UI.WebControls.ModelDataSourceView.EvaluateSelectMethodParameters"/>.
        /// </param>
        /// <param name="result">The result after operations like auto paging/sorting are done.</param>
        /// <returns></returns>
        protected virtual object ProcessSelectMethodResult(DataSourceSelectArguments arguments, DataSourceSelectResultProcessingOptions selectResultProcessingOptions, ModelDataMethodResult result) {
            // If the return value is null, there is no more processing to be done
            if (result.ReturnValue == null) {
                return null;
            }

            bool autoPage = selectResultProcessingOptions.AutoPage;
            bool autoSort = selectResultProcessingOptions.AutoSort;
            Type modelType = selectResultProcessingOptions.ModelType;
            string sortExpression = arguments.SortExpression;

            if (autoPage) {
                MethodInfo countHelperMethod = typeof(QueryableHelpers).GetMethod("CountHelper").MakeGenericMethod(modelType);
                arguments.TotalRowCount = (int)countHelperMethod.Invoke(null, new object[] { result.ReturnValue });

                //Bug 180907: We would like to auto sort on DataKeyName when paging is enabled and result is not already sorted by user to overcome a limitation in EF.
                MethodInfo isOrderingMethodFoundMethod = typeof(QueryableHelpers).GetMethod("IsOrderingMethodFound").MakeGenericMethod(modelType);
                bool isOrderingMethodFound = (bool)isOrderingMethodFoundMethod.Invoke(null, new object[] { result.ReturnValue });
                if (!isOrderingMethodFound) {
                    if (String.IsNullOrEmpty(sortExpression) && !String.IsNullOrEmpty(DataKeyName)) {
                        autoSort = true;
                        selectResultProcessingOptions.AutoSort = true;
                        sortExpression = DataKeyName;
                    }
                }
            }
            else if (arguments.StartRowIndex >= 0 && arguments.MaximumRows > 0) {
                //When paging is handled by developer, we need to set the TotalRowCount parameter from the select method out parameter.
                arguments.TotalRowCount = (int)result.OutputParameters[TotalRowCountParameterName];
            }

            if (autoPage || autoSort) {
                MethodInfo sortPageHelperMethod = typeof(QueryableHelpers).GetMethod("SortandPageHelper").MakeGenericMethod(modelType);
                object returnValue = sortPageHelperMethod.Invoke(null, new object[] { result.ReturnValue, 
                                                                                            autoPage ? (int?)arguments.StartRowIndex : null,
                                                                                            autoPage ? (int?)arguments.MaximumRows : null,
                                                                                            autoSort ? sortExpression : null });
                return returnValue;
            }

            return result.ReturnValue;
        }
        private ModelDataSourceMethod EvaluateSelectMethodParameters(DataSourceSelectArguments arguments, ModelDataSourceMethod method, bool isAsyncSelect, out DataSourceSelectResultProcessingOptions selectResultProcessingOptions) {
            IOrderedDictionary mergedParameters = MergeSelectParameters(arguments);
            // Resolve the method
            method = method ?? FindMethod(SelectMethod);

            Type selectMethodReturnType = method.MethodInfo.ReturnType;
            if (isAsyncSelect) {
                selectMethodReturnType = ExtractAsyncSelectReturnType(selectMethodReturnType);
            }

            Type modelType = ModelType;
            if (modelType == null) {
                //When ModelType is not specified but SelectMethod returns IQueryable<T>, we treat T as model type for auto paging and sorting.
                //If the return type is something like CustomType<U,T> : IQueryable<T>, we should use T for paging and sorting, hence
                //we walk over the return type's generic arguments for a proper match.
                foreach (Type typeParameter in selectMethodReturnType.GetGenericArguments()) {
                    if (typeof(IQueryable<>).MakeGenericType(typeParameter).IsAssignableFrom(selectMethodReturnType)) {
                        modelType = typeParameter;
                    }
                }
            }
            Type queryableModelType = (modelType != null) ? typeof(IQueryable<>).MakeGenericType(modelType) : null;

            //We do auto paging or auto sorting when the select method is returning an IQueryable and does not have parameters for paging or sorting.
            bool isReturningQueryable = queryableModelType != null && queryableModelType.IsAssignableFrom(selectMethodReturnType);

            if (isAsyncSelect && isReturningQueryable) {
                // async select method does not support returning IQueryable<>.
                throw new InvalidOperationException(SR.GetString(SR.ModelDataSourceView_InvalidAsyncSelectReturnType, modelType));
            }

            bool autoPage = false;
            bool autoSort = false;

            if (arguments.StartRowIndex >= 0 && arguments.MaximumRows > 0) {
                autoPage = IsAutoPagingRequired(method.MethodInfo, isReturningQueryable, isAsyncSelect);

                if (isAsyncSelect) {
                    Debug.Assert(!autoPage, "auto-paging should not be true when using async select method");

                    // custom paging is not supported if the return type is not SelectResult
                    if (typeof(SelectResult) != selectMethodReturnType) {
                        throw new InvalidOperationException(SR.GetString(SR.ModelDataSourceView_MustUseSelectResultAsReturnType));
                    }
                }
            }

            if (!String.IsNullOrEmpty(arguments.SortExpression)) {
                autoSort = IsAutoSortingRequired(method.MethodInfo, isReturningQueryable);
            }

            selectResultProcessingOptions = new DataSourceSelectResultProcessingOptions() { ModelType = modelType, AutoPage = autoPage, AutoSort = autoSort };
            EvaluateMethodParameters(DataSourceOperation.Select, method, mergedParameters);
            return method;
        }
 /// <summary>
 /// Evaluates the select method parameters and also determines the options for processing select result like auto paging and sorting behavior.
 /// </summary>
 /// <param name="arguments">The DataSourceSelectArguments for the select operation.</param>
 /// <param name="selectResultProcessingOptions">The <see cref="System.Web.UI.WebControls.DataSourceSelectResultProcessingOptions"/> to use 
 /// for processing the select result once select operation is complete. These options are determined in this method and later used
 /// by the method <see cref="System.Web.UI.WebControls.ModelDataSourceView.ProcessSelectMethodResult"/>.
 /// </param>
 /// <returns>A <see cref="System.Web.UI.WebControls.ModelDataSourceMethod"/> with the information required to invoke the select method.</returns>
 protected virtual ModelDataSourceMethod EvaluateSelectMethodParameters(DataSourceSelectArguments arguments, out DataSourceSelectResultProcessingOptions selectResultProcessingOptions) {
     return EvaluateSelectMethodParameters(arguments, null/*method*/, false /*isAsyncSelect*/, out selectResultProcessingOptions);
 }
Ejemplo n.º 6
0
        /// <summary>
        /// This method performs operations on the select method result like auto paging and sorting if applicable.
        /// </summary>
        /// <param name="arguments">The DataSourceSelectArguments for the select operation.</param>
        /// <param name="selectResultProcessingOptions">The <see cref="System.Web.UI.WebControls.DataSourceSelectResultProcessingOptions"/> to use for processing the select result.
        /// These options are determined in an earlier call to <see cref="System.Web.UI.WebControls.ModelDataSourceView.EvaluateSelectMethodParameters"/>.
        /// </param>
        /// <param name="result">The result after operations like auto paging/sorting are done.</param>
        /// <returns></returns>
        protected virtual object ProcessSelectMethodResult(DataSourceSelectArguments arguments, DataSourceSelectResultProcessingOptions selectResultProcessingOptions, ModelDataMethodResult result)
        {
            // If the return value is null, there is no more processing to be done
            if (result.ReturnValue == null)
            {
                return(null);
            }

            bool   autoPage       = selectResultProcessingOptions.AutoPage;
            bool   autoSort       = selectResultProcessingOptions.AutoSort;
            Type   modelType      = selectResultProcessingOptions.ModelType;
            string sortExpression = arguments.SortExpression;

            if (autoPage)
            {
                MethodInfo countHelperMethod = typeof(QueryableHelpers).GetMethod("CountHelper").MakeGenericMethod(modelType);
                arguments.TotalRowCount = (int)countHelperMethod.Invoke(null, new object[] { result.ReturnValue });

                //Bug 180907: We would like to auto sort on DataKeyName when paging is enabled and result is not already sorted by user to overcome a limitation in EF.
                MethodInfo isOrderingMethodFoundMethod = typeof(QueryableHelpers).GetMethod("IsOrderingMethodFound").MakeGenericMethod(modelType);
                bool       isOrderingMethodFound       = (bool)isOrderingMethodFoundMethod.Invoke(null, new object[] { result.ReturnValue });
                if (!isOrderingMethodFound)
                {
                    if (String.IsNullOrEmpty(sortExpression) && !String.IsNullOrEmpty(DataKeyName))
                    {
                        autoSort = true;
                        selectResultProcessingOptions.AutoSort = true;
                        sortExpression = DataKeyName;
                    }
                }
            }
            else if (arguments.StartRowIndex >= 0 && arguments.MaximumRows > 0)
            {
                //When paging is handled by developer, we need to set the TotalRowCount parameter from the select method out parameter.
                arguments.TotalRowCount = (int)result.OutputParameters[TotalRowCountParameterName];
            }

            if (autoPage || autoSort)
            {
                MethodInfo sortPageHelperMethod = typeof(QueryableHelpers).GetMethod("SortandPageHelper").MakeGenericMethod(modelType);
                object     returnValue          = sortPageHelperMethod.Invoke(null, new object[] { result.ReturnValue,
                                                                                                   autoPage ? (int?)arguments.StartRowIndex : null,
                                                                                                   autoPage ? (int?)arguments.MaximumRows : null,
                                                                                                   autoSort ? sortExpression : null });
                return(returnValue);
            }

            return(result.ReturnValue);
        }
        /// <summary>
        /// Evaluates the select method parameters and also determines the options for processing select result like auto paging and sorting behavior.
        /// </summary>
        /// <param name="arguments">The DataSourceSelectArguments for the select operation.</param>
        /// <param name="selectResultProcessingOptions">The <see cref="System.Web.UI.WebControls.DataSourceSelectResultProcessingOptions"/> to use 
        /// for processing the select result once select operation is complete. These options are determined in this method and later used
        /// by the method <see cref="System.Web.UI.WebControls.ModelDataSourceView.ProcessSelectMethodResult"/>.
        /// </param>
        /// <returns>A <see cref="System.Web.UI.WebControls.ModelDataSourceMethod"/> with the information required to invoke the select method.</returns>
        protected virtual ModelDataSourceMethod EvaluateSelectMethodParameters(DataSourceSelectArguments arguments, out DataSourceSelectResultProcessingOptions selectResultProcessingOptions) {
            ModelDataSourceMethod method;
            IOrderedDictionary mergedParameters = MergeSelectParameters(arguments);
            // Resolve the method
            method = FindMethod(SelectMethod);

            Type selectMethodReturnType = method.MethodInfo.ReturnType;
            Type modelType = ModelType;
            if (modelType == null) {
                //When ModelType is not specified but SelectMethod returns IQueryable<T>, we treat T as model type for auto paging and sorting.
                //If the return type is something like CustomType<U,T> : IQueryable<T>, we should use T for paging and sorting, hence
                //we walk over the return type's generic arguments for a proper match.
                foreach (Type typeParameter in selectMethodReturnType.GetGenericArguments()) {
                    if (typeof(IQueryable<>).MakeGenericType(typeParameter).IsAssignableFrom(selectMethodReturnType)) {
                        modelType = typeParameter;
                    }
                }
            }
            Type queryableModelType = (modelType != null) ? typeof(IQueryable<>).MakeGenericType(modelType) : null;

            //We do auto paging or auto sorting when the select method is returning an IQueryable and does not have parameters for paging or sorting.
            bool isReturningQueryable = queryableModelType != null && queryableModelType.IsAssignableFrom(selectMethodReturnType);

            bool autoPage = false;
            bool autoSort = false;

            if (arguments.StartRowIndex >= 0 && arguments.MaximumRows > 0) {
                autoPage = IsAutoPagingRequired(method.MethodInfo, isReturningQueryable);
            }

            if (!String.IsNullOrEmpty(arguments.SortExpression)) {
                autoSort = IsAutoSortingRequired(method.MethodInfo, isReturningQueryable);
            }

            selectResultProcessingOptions = new DataSourceSelectResultProcessingOptions() { ModelType = modelType, AutoPage = autoPage, AutoSort = autoSort };
            EvaluateMethodParameters(DataSourceOperation.Select, method, mergedParameters);
            return method;
        }