我在我的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 :(得分: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,但想法仍然相同
答案 1 :(得分: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);
}
}
答案 2 :(得分:0)
="IDclient_logindata=" & Forms!NavigationForm!clientlist.Form!IDclient