예제 #1
0
        /// <summary>
        /// Applies default sorting behavior to the query.
        /// These sorting behaviors are those added with [DefaultOrderBy] attributes on model properties.
        /// If no default orderings are found, an attempt will be made to sort on a property called "Name" if one exists,
        /// and finally, on the primary key of the model being requested.
        /// This is called by ApplyListSorting when constructing a list result.
        /// </summary>
        /// <param name="query">The query to sort.</param>
        /// <returns>The new query with additional sorting applied.</returns>
        public virtual IQueryable <T> ApplyListDefaultSorting(IQueryable <T> query)
        {
            // Use the DefaultOrderBy attributes if available
            var defaultOrderBy = ClassViewModel.DefaultOrderByClause();

            if (defaultOrderBy != null)
            {
                query = query.OrderBy(defaultOrderBy);
            }
            return(query);
        }
예제 #2
0
        protected async Task <ListResult> ListImplementation(ListParameters listParameters)
        {
            try
            {
                IQueryable <T> result = GetListDataSource(listParameters);

                // Add the Include statements to the result to grab the right object graph. Passing "" gets the standard set.
                if ((result is DbSet <T>) && string.Compare(listParameters.Includes, "none", StringComparison.InvariantCultureIgnoreCase) != 0)
                {
                    result = result.Includes(listParameters.Includes);
                }

                // Add filters for the where clause, etc.
                result = AddFilters(result, listParameters);

                // Change to a list so we can sort on other fields not just what is in the database if we need to.
                // TODO: Make this more flexible to allow for searching on computed terms. This could be automatic by detecting fields that are in the database.
                // IEnumerable<T> result2 = result;
                // if (listParameters.ToList) result2 = result.ToList() as IQueryable<T>;
                // Above was removed because IEnumerable uses different extension methods than iQueryable causing very inefficient SQL to be used.

                // Add sorting.
                var orderByParams = listParameters.OrderByList;
                if (orderByParams.Any())
                {
                    foreach (var orderByParam in orderByParams)
                    {
                        string fieldName = orderByParam.Key;
                        var    prop      = ClassViewModel.PropertyByName(fieldName);
                        if (!fieldName.Contains(".") && prop != null && prop.IsPOCO)
                        {
                            string clause = prop.Type.ClassViewModel.DefaultOrderByClause($"{fieldName}.");
                            clause = clause.Replace("ASC", orderByParam.Value.ToUpper());
                            clause = clause.Replace("DESC", orderByParam.Value.ToUpper());
                            result = result.OrderBy(clause);
                        }
                        else
                        {
                            result = result.OrderBy(string.Join(", ", orderByParams.Select(f => $"{fieldName} {f.Value}")));
                        }
                    }
                }
                else
                {
                    // Use the DefaultOrderBy attributes if available
                    var defaultOrderBy = ClassViewModel.DefaultOrderByClause();
                    if (defaultOrderBy != null)
                    {
                        result = result.OrderBy(defaultOrderBy);
                    }
                    // Use the Name property if it exists.
                    else if (ClassViewModel.Properties.Any(f => f.Name == "Name"))
                    {
                        result = result.OrderBy("Name");
                    }
                    // Use the ID property.
                    else
                    {
                        result = result.OrderBy(ClassViewModel.PrimaryKey.Name);
                    }
                }

                // Get a count
                int totalCount;
                if (result is IAsyncQueryProvider)
                {
                    totalCount = await result.CountAsync();
                }
                else
                {
                    totalCount = result.Count();
                }


                // Add paging.
                int page     = listParameters.Page ?? 1;
                int pageSize = listParameters.PageSize ?? DefaultPageSize;
                // Fix the page numbers if necessary
                if ((page - 1) * pageSize > totalCount)
                {
                    page = (int)((totalCount - 1) / pageSize) + 1;
                }
                // Skip zero has issues.
                // Due to a bug in both RC1 (fails in SQL 2008) and RC2 (doesn't get all included children)
                if (page > 1)
                {
                    result = result.Skip((page - 1) * pageSize);
                }
                result = result.Take(pageSize);

                // Make the database call
                IEnumerable <T> result2;
                if (result is IAsyncQueryProvider)
                {
                    result2 = await result.ToListAsync();
                }
                else
                {
                    result2 = result.ToList();
                }

                // Add external entities
                result2.IncludesExternal(listParameters.Includes);

                // Exclude certain data
                if (new T() is IExcludable)
                {
                    foreach (var obj in result2)
                    {
                        ((IExcludable)obj).Exclude(listParameters.Includes);
                    }
                }

                // Allow for security trimming
                // TODO: This needs to be adjusted to handle paging correctly.
                var result3 = result2.Where(f => BeforeGet(f));

                var tree = result.GetIncludeTree();
                IEnumerable <TDto> result4 = result3.ToList().Select(obj => MapObjToDto(obj, listParameters.Includes, tree)).ToList();

                if (listParameters.FieldList.Any())
                {
                    return(new ListResult(result4.ToList().Select("new (" + string.Join(", ", listParameters.FieldList) + ")"),
                                          page, totalCount, pageSize));
                }
                return(new ListResult(result4, page, totalCount, pageSize));
            }
            catch (Exception ex)
            {
                Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
                if (Logger != null)
                {
                    Logger.LogError(ex.Message, ex);
                }
                return(new ListResult(ex));
            }
        }