2010-01-09 117 views
15

我想知道人们如何在asp.net mvc中对表进行排序? 我听说过JavaScript解决方案可以很好地处理非分页表,比如jquery的表分类器,但是我需要一个可以与分页表一起工作的解决方案。在asp.net中对表进行排序MVC

我正在处理的项目目前使用以下解决方案,但我觉得它非常混乱。

控制器

public ActionResult Sort(string parameter) 
{ 

IEnumerable<IProduct> list; 

if (Session["Model"] != null) 
    list = (IEnumerable<IProduct>)Session["Model"]).ToList<IProduct>(); 
else 
    list = _service.GetAll(); 

if (Session["parameter"] == null && Session["sortDirection"] == null) 
{ 
    //set the parameter and set the sort to desc 
    Session["parameter"] = parameter; 
    Session["sortDirection"] = "DESC"; 
} 
else if (Session["parameter"] != null) //already set so not the first time 
{ 
    //same parameter sent 
    if (Session["parameter"].ToString().Equals(parameter)) 
    { 
    //check sort direction and reverse 
    if (Session["sortDirection"].ToString().Equals("DESC")) 
    Session["sortDirection"] = "ASC"; 
    else 
    Session["sortDirection"] = "DESC"; 
    } 
    else //different parameter sent 
    { 
    Session["sortDirection"] = "DESC"; 
    Session["parameter"] = parameter; 
    } 
} 

if (Session["sortDirection"].CompareTo("ASC") == 0) 
    list = Models.ContollerHelpers.SortingHelper.OrderBy(list.AsQueryable(), column); 
else 
    list = Models.ContollerHelpers.SortingHelper.OrderByDescending(list.AsQueryable(), column); 

return View("Results", list.ToList); 
} 

助手

public class Helper() 
{ 
private static IOrderedQueryable<T> OrderingHelper<T>(IQueryable<T> source, string propertyName, bool descending, bool anotherLevel) 
{ 
    ParameterExpression param = Expression.Parameter(typeof(T), string.Empty); // I don't care about some naming 
    MemberExpression property = Expression.PropertyOrField(param, propertyName); 
    LambdaExpression sort = Expression.Lambda(property, param); 

    MethodCallExpression call = Expression.Call(
    typeof(Queryable), 
    (!anotherLevel ? "OrderBy" : "ThenBy") + (descending ? "Descending" : string.Empty), 
    new[] { typeof(T), property.Type }, 
    source.Expression, 
    Expression.Quote(sort)); 

    return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(call); 
} 

public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName) 
{ 
    return OrderingHelper(source, propertyName, false, false); 
} 

public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string propertyName) 
{ 
    return OrderingHelper(source, propertyName, true, false); 
} 

public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string propertyName) 
{ 
    return OrderingHelper(source, propertyName, false, true); 
} 

public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source, string propertyName) 
{ 
    return OrderingHelper(source, propertyName, true, true); 
} 
} 

列表视图

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Models.Interface.IProduct>>" %> 
<% Session["model"] = Model; %> 
<table> 
    <tr> 
    <th> 
    Edit Details 
    </th> 
    <th> 
    <%=Html.ActionLink("Id","Sort",new {parameter ="Id"}) %> 
    </th> 
    <th> 
    <%=Html.ActionLink("Name", "Sort", new { parameter = "Name"})%> 
    </th> 
    <th> 
    <%=Html.ActionLink("Status", "Sort", new { parameter = "Status" })%> 
    </th> 
    <th> 
    <%=Html.ActionLink("Notes", "Sort", new { parameter = "Notes"})%> 
    </th> 
    </tr> 
    <% foreach (var item in Model){ %> 

    <tr> 
    <td> 
    <%= Html.ActionLink("Edit", "Edit", new { id=item.Id }) %> | 
    </td> 
    <td> 
    <%= Html.Encode(item.Id) %> 
    </td> 
    <td> 
    <%= Html.Encode(item.Name) %> 
    </td> 
    <td> 
    <%= Html.Encode(item.Status) %> 
    </td> 
    <td> 
    <%= Html.Encode(item.Notes) %> 
    </td> 
    </tr> 

    <% } %> 
    </table> 

这是d的唯一途径像这样的东西? 如果有人知道一种更好的方式,不需要将所有记录一次加载到页面上,那么请链接到示例。

+0

@AlteredConcept的q是过于宽泛,在u的不是说什么ü最关心的。它是否是视图(几乎没有,因为它非常简单),以linq的通用方式进行排序的方式,使用session来保存参数,使用“参数”或其解析。 – eglasius 2010-01-13 18:01:37

+0

对不起。管制员是最让我困扰的。我不想在每个控制器中为每个实体列表视图重复所有代码。这是很多重复的代码。我试图找出一种方法,我可以把它放在一个基本的控制器,但运行一个空白。所以我期待着看看别人是否有更好的更优雅的分类方法 – AlteredConcept 2010-01-13 19:32:09

+0

谢谢。我头疼。 – 2010-01-17 17:20:59

回答

10

退房@DataTables这将让你页面的搜索结果,并配备简易安装查询它的数据表。它适用于Ajax和json数据。看样品。希望这会帮助你。

+0

+1。我在ASP.NET MVC应用程序中用服务器端处理(http://datatables.net/usage/server-side)成功地使用了DataTables jQuery插件。 – 2010-01-09 06:42:29

+2

这会将所有数据加载到加载时的页面上(即使在加载后页面上的数据)。尝试一次加载超过1000条记录。显示页面需要一段时间。 – AlteredConcept 2010-01-09 21:35:36

+1

正如Anton指出的那样,使用服务器端处理仅向客户端http://datatables.net/usage/server-side发送显示的行。 – 2010-01-13 13:08:43

7

尝试下面的扩展方法(从头部的顶部):

​​

用法:

var products = Session["Model"] as IEnumerable<Product>() ?? _service.GetAll(); 

return products.OrderBy("Name", "ASC").ThenBy("Price", "DESC"); 

假设你只使用1周的OrderBy条件在时间可以使用:

var products = Session["Model"] as IEnumerable<Product>(); 

var sortDirection = Session["Direction"] as string ?? "DESC"; 
Session["Direction"] = sortDirection == "DESC" ? "ASC" : "DESC"; 
sortDirection = Session["Direction"] as string; 

return products.OrderBy(parameter, sortDirection); 
+0

不应该direction.ToLower()是direction.ToUpper()? – AlteredConcept 2010-01-14 02:06:18

+0

正确。感谢您指出这一点,我在记事本中写下这些东西:-) – 2010-01-14 09:12:01

+0

没问题。我喜欢这种方法,但我遇到了一些问题。有时它会正确排序,有时不正确(而不是递增,反之亦然)。 – AlteredConcept 2010-01-14 18:48:49

4

如果JavaScript被禁用,则说明您有问题。

我想去一个noscript解决方案。

我有两个单选按钮组:

direction: () ascending (.) descending 

orderBy: (.) Id () Name () Status 

我对待查看形式有多个提交按钮:

(没有JavaScript)~~同名为两个按钮。

就在你身上。aspx页面,添加三个按钮:

<input type="submit" value="Requery" name="submitButton"/> 
<input type="submit" value="Previous" name="submitButton"/> 
<input type="submit" value="Next"  name="submitButton"/> 

控制器

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Sort(string direction, string orderBy, string submitButton) 
{ 
    if (submitButton == "Requery")  //et cetera 

TMTOWTDI:有不止一种方法来做到这

0

肯定喜欢简的解决方案 - 非常感谢lot Jan ...您刚刚用解析每个列标题的case语句为我节省了大约60行代码。当使用两个会话变量时,该解决方案“实现了极佳的切换点击,仅对表格中的1列解决方案进行排序”,其中一个将ASC/DESC保留为布尔值,另一个保存类型/列名称。

我使用了这个C#示例扩展,并在今天下午用VB实现它。我设法将30行的case case语句分成一行代码。

在视图:

<th>Date <a class="clickable" href="<%=Url.Action("SortStationVisits", New With {.SortField = "PlanningDate"})%>"><span class="colSort" style="display: inline-table;"></span></a></th> 

所述延伸部(公共模块OrderByExtender):

Imports System.Linq.Expressions 

Public Function OrderBy(Of T)(collection As IEnumerable(Of T), key As String, isDescending As Boolean) As IOrderedEnumerable(Of T) 
    Dim sortLambda As LambdaExpression = BuildLambda(Of T)(key) 
    If isDescending Then 
     Return collection.OrderByDescending(DirectCast(sortLambda.Compile(), Func(Of T, Object))) 
    Else 
     Return collection.OrderBy(DirectCast(sortLambda.Compile(), Func(Of T, Object))) 
    End If 
End Function 

Public Function ThenBy(Of T)(collection As IOrderedEnumerable(Of T), key As String, isDescending As Boolean) As IOrderedEnumerable(Of T) 
    Dim sortLambda As LambdaExpression = BuildLambda(Of T)(key) 

    If (isDescending) Then 
     Return collection.ThenByDescending(DirectCast(sortLambda.Compile(), Func(Of T, Object))) 
    Else 
     Return collection.ThenBy(DirectCast(sortLambda.Compile(), Func(Of T, Object))) 
    End If 
End Function 

Private Function BuildLambda(Of T)(key As String) As LambdaExpression 
    Dim TParameterExpression As ParameterExpression = Expression.Parameter(GetType(T), "p") 
    Dim sortLambda As LambdaExpression = Expression.Lambda(Expression.Convert(Expression.[Property](TParameterExpression, key), GetType(Object)), TParameterExpression) 
    Return sortLambda 
End Function 

AT控制器动作:

Public Function SortStationVisits(Optional page As Integer = 1, Optional SortField As String = "") As ActionResult 
    Dim sps = LoadSession() 

    If SortField = sps.StationVisitSorter Then 
     sps.StationVisitDescOrder = Not (sps.StationVisitDescOrder) 
    Else 
     sps.StationVisitDescOrder = False 
    End If 

    sps.StationVisitSorter = SortField 

    SaveSession(sps) 
    Return RedirectToAction("Show") 
End Function 

在控制器Show方法(1行代码W00T的!):

spv.SelectableStationVisits = spv.SelectableStationVisits.OrderBy(sps.StationVisitSorter, sps.StationVisitDescOrder).ToList