0

我在我的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); 
    } 

我试了几个东西,使其中的这个一般没有完全工作 - 有些是因为我对所有列等其他原因筛选事实。我希望有一个更好的方法来做到这一点,所以我可以传递列或函数来选择列,并使其工作。

+0

你是在一个IEnumerable从您的存储库这样做,这将是存储库中更好。当我这样做时,我使用dapper http://code.google.com/p/dapper-dot-net/用于大型表格,而客户端筛选用于较小的表格,因为EF查询可能会变得很大而且复杂类型的东西。 – 2013-02-24 19:40:42

+0

我确实将一个存储库(DdContext)列表作为IEnumerable传递,以便任何控制器都可以使用它。 – Mensur 2013-02-26 00:49:16

回答

0

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

results.OrderBy( “ID降序”)

results.Where( “Name.Contains( '富')”)

希望这些帮助:

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,但这个想法是一样的

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); 
    } 
} 
+0

上面的帮助程序方法可以像以下任何其他查询帮助程序一样使用: this.DbContext.TrainingSessions.Where(x => x.RegistrationDeadline> DateTime.Now).SortingAndPaging(sortAndPagingInfo).ToList(); – SumanReddy 2016-04-15 23:20:29

+0

“SortingAndPagingInfo”类的定义在哪里? – Shiva 2017-03-11 02:02:09

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); 
     } 
    }