1

我在我的 MVC4 应用程序中使用 jQuery 数据表 ( http://www.datatables.net ),您可能知道该表允许服务器端处理。我将在绑定到多个控制器的多个视图中使用该表,因此我想实现一种通用的方法来过滤、排序和分页数据,而无需为每个控制器编写方法。如果我这样做,它们看起来都一样,但它们会针对数据库中的不同实体,并对不同的列进行文本过滤和排序。这是我今天要做的:

    public virtual ActionResult AjaxHandler(jQueryDataTableParamModel param)
    {
        var myProducts = _productRepository.Products;
        IEnumerable<Product> filteredProducts = myProducts;

        // Filtering
        if (!string.IsNullOrEmpty(param.sSearch))
        {
            var searchTermLower = param.sSearch.Trim().ToLower();
            filteredProducts = filteredProducts
                     .Where(c => c.Title.Contains(param.sSearch)
                                 ||
                      c.Manufacturer.ManufacturerName.ToLower().Contains(searchTermLower)
                                 ||
                      c.Category.CategoryTitle.ToLower().Contains(searchTermLower)
                                 ||
                      c.Size.Title.ToLower().Contains(searchTermLower)
                                 ||
                      c.Price.ToString("C").Contains(searchTermLower));
        }

        // Sorting
        var sortColumnIndex = Convert.ToInt32(Request["iSortCol_0"]);
        var sortDirection = Request["sSortDir_0"];
        if (sortColumnIndex == 0)
        {
            filteredProducts = sortDirection == "asc" ? filteredProducts.OrderBy(x => x.CreatedDate) : filteredProducts.OrderByDescending(x => x.CreatedDate);
        }
        else if (sortColumnIndex == 1)
        {
            filteredProducts = sortDirection == "asc" ? filteredProducts.OrderBy(x => x.Title) : filteredProducts.OrderByDescending(x => x.Title);
        }
        else if (sortColumnIndex == 2)
        {
            filteredProducts = sortDirection == "asc" ? filteredProducts.OrderBy(x => x.Manufacturer.ManufacturerName) : filteredProducts.OrderByDescending(x => x.Manufacturer.ManufacturerName);
        }
        else if (sortColumnIndex == 3)
        {
            filteredProducts = sortDirection == "asc" ? filteredProducts.OrderBy(x => x.Size.Title) : filteredProducts.OrderByDescending(x => x.Size.Title);
        }
        else if (sortColumnIndex == 4)
        {
            filteredProducts = sortDirection == "asc" ? filteredProducts.OrderBy(x => x.Category.CategoryTitle) : filteredProducts.OrderByDescending(x => x.Category.CategoryTitle);
        }
        else if (sortColumnIndex == 4)
        {
            filteredProducts = sortDirection == "asc" ? filteredProducts.OrderBy(x => x.Price) : filteredProducts.OrderByDescending(x => x.Price);
        }

        // Paging
        var displayedProducts = filteredProducts.Skip(param.iDisplayStart).Take(param.iDisplayLength);
        var result = from c in displayedProducts
                     select new[] { c.ProductId.ToString(CultureInfo.InvariantCulture), c.CreatedDate.ToString("G"), c.Title, c.Manufacturer.ManufacturerName, c.Size.Title, c.Category.CategoryTitle, c.Price.ToString("C") };
        return Json(new
        {
            sEcho = param.sEcho,
            iTotalRecords = myProducts.Count(),
            iTotalDisplayRecords = filteredProducts.Count(),
            aaData = result
        }, JsonRequestBehavior.AllowGet);
    }

我尝试了几件事来使这个通用的没有一个完全有效 - 有些是因为我过滤所有列和其他原因是因为其他原因。我希望有更好的方法来做到这一点,这样我就可以传递选择列的列或函数并让它工作。

4

3 回答 3

0

最近刚刚处理了这个问题,我可以告诉你,你想在你的项目中实现动态 linq。动态 linq 允许您编写查询,例如

results.OrderBy("id desc")

results.Where("Name.Contains('foo')")

希望这些帮助:

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx http://codefucius.blogspot.com /2012/11/implementing-jqgrid-search.html

注意 - 我使用了 jqGrid,但想法保持不变

于 2013-02-25T00:05:44.207 回答
0

动态 SortingAndPagingHelper 扩展方法

/// <summary>
/// Extension method for sorting and filtering
/// </summary>
public static class SortingAndPagingHelper
{
    public static IEnumerable<TSource> SortingAndPaging<TSource>(this IEnumerable<TSource> source, SortingAndPagingInfo sortingModal)
    {
        // Gets the coloumn name that sorting to be done on
        PropertyInfo propertyInfo = source.GetType().GetGenericArguments()[0].GetProperty(sortingModal.SortColumnName);

        // sorts by ascending if sort criteria is Ascending otherwise sorts descending
        return sortingModal.SortOrder == "Ascending" ? source.OrderByDescending(x => propertyInfo.GetValue(x, null)).Skip(sortingModal.PageSelected * sortingModal.PageSize).Take(sortingModal.PageSize)
                           : source.OrderBy(x => propertyInfo.GetValue(x, null)).Skip(sortingModal.PageSelected * sortingModal.PageSize).Take(sortingModal.PageSize);
    }
}
于 2016-04-15T23:09:43.073 回答
0
    /// Used to indicate the sort order.
    /// </summary>
    public enum SortOrder
    {
        /// <summary>
        /// Indicates whether the order is ascending.
        /// </summary>
        Ascending = 0,

        /// <summary>
        /// Indicates whether the order is descending.
        /// </summary>
        Descending = 1,

        /// <summary>
        /// Indicates whether the order is neutral.
        /// </summary>
        Neutral = 2
    }

    /// <summary>
    /// DTO for sorting and paging
    /// </summary>
    public class FilterProperties
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="FilterProperties"/> class.
        /// </summary>
        public FilterProperties()
        {
            // parameterless constructor
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FilterProperties"/> class.
        /// </summary>
        /// <param name="sortColumnName">column name of sorting.</param>
        /// <param name="sortOrder">order of the sorting</param>
        /// <param name="pageSize">items in the page.</param>
        /// <param name="filterValue">value of the filter.</param>
        /// <param name="pageselected">current page selected.</param>
        public FilterProperties(string sortColumnName, SortOrder sortOrder, int pageSize, string filterValue = "All", int pageselected = 0)
        {
            this.SortColumnName = sortColumnName;
            this.SortOrder = sortOrder;
            this.PageSize = pageSize;
            this.PageSelected = pageselected;
            this.FilterValue = filterValue;
        }

        /// <summary>
        /// Gets or sets the filter column name
        /// </summary>
        public string FilterColumnName { get; set; }

        /// <summary>
        /// Gets or sets the filter value
        /// </summary>
        public string FilterValue { get; set; }

        /// <summary>
        /// Gets or sets the sort field name.
        /// </summary>
        public string SortColumnName { get; set; }

        /// <summary>
        /// Gets or sets the sort direction.
        /// </summary>
        public SortOrder SortOrder { get; set; }

        /// <summary>
        /// Gets or sets the page size.
        /// </summary>
        [Obsolete("Use RecordCount instead (remove this)")]
        public int PageSize { get; set; }

        /// <summary>
        /// Gets or sets the current page index.
        /// </summary>
        [Obsolete("Use StartRecord instead (remove this)")]
        public int PageSelected { get; set; }

        /// <summary>
        /// Gets or sets the zero-based index of the starting record to return in
        /// the filtered result set.         
        /// </summary>
        public int StartRecord { get; set; }

        /// <summary>
        /// Gets or sets the number of records to return in the filtered result set.         
        /// </summary>
        public int RecordCount { get; set; }
    }
}

Extension Method for sorting and paging
public static class SortingAndPagingHelper
    {
        /// <summary>
        /// Returns the list of items of type on which method called
        /// </summary>
        /// <typeparam name="TSource">This helper can be invoked on IEnumerable type.</typeparam>
        /// <param name="source">instance on which this helper is invoked.</param>
        /// <param name="sortingModal">Page no</param>
        /// <returns>List of items after query being executed on</returns>
        public static IEnumerable<TSource> SortingAndPaging<TSource>(
            this IEnumerable<TSource> source, 
            FilterProperties sortingModal)
        {
            // Is there any sort column supplied?
            IEnumerable<TSource> data = source;
            if (!string.IsNullOrEmpty(sortingModal.SortColumnName))
            {
                // Gets the coloumn name that sorting to be done on
                PropertyInfo propertyInfo =
                    data.GetType().GetGenericArguments()[0].GetProperty(sortingModal.SortColumnName);

                // Define the sorting function
                data = sortingModal.SortOrder == SortOrder.Ascending
                    ? data.OrderBy(x => propertyInfo.GetValue(x, null))
                    : data.OrderByDescending(x => propertyInfo.GetValue(x, null));
            }

            // Apply paging to (sorted) data
            return sortingModal.RecordCount > 0
                ? data.Skip(sortingModal.StartRecord).Take(sortingModal.RecordCount)
                : data.Skip((sortingModal.PageSelected - 1) * sortingModal.PageSize).Take(sortingModal.PageSize);
        }
    }
于 2017-05-02T16:10:12.950 回答