如何为我的MVC asp.net Core应用添加排序功能?

时间:2018-11-06 16:57:45

标签: c# asp.net sorting asp.net-core-mvc asp.net-core-2.0

我有一个MVC应用程序,用户可以在其中记录其创建条目,并在屏幕上的表格中查看它们。我想添加一个功能,用户可以在其中单击 Name 标头,然后按名称列对表进行排序。我正在使用this docs.Microsoft tutorial来帮助我,但我似乎什么都没得到。这是我到目前为止的内容:

控制器:

public async Task<IActionResult> Index(string sortOrder)
    {
        ViewData["NameSortParm"] = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
        ViewData["DateSortParm"] = sortOrder == "Date" ? "date_desc" : "Date";
        var logs = from l in _context.Log
                        select l;
        switch (sortOrder)
        {
            case "name_desc":
                logs = logs.OrderByDescending(l => l.Name);
                break;
            case "Date":
                logs = logs.OrderBy(l => l.Date);
                break;
            case "date_desc":
                logs = logs.OrderByDescending(l => l.Date);
                break;
            case "relation":
                logs = logs.OrderByDescending(l => l.Relation);
                break;
            case "type":
                logs = logs.OrderByDescending(l => l.Type);
                break;
            default:
                logs = logs.OrderBy(l => l.Date);
                break;
        }
        return View(await logs.AsNoTracking().ToListAsync());
    }

    public async Task OnGetAsync(string parentComment, string searchString)
    {
        // Use LINQ to get list of dates.
        IQueryable<DateTime> dateQuery = from m in _context.Log
                                        // orderby m.Date
                                        select m.Date;

        var logs = from l in _context.Log
                     select l;

        if (!String.IsNullOrEmpty(searchString))
        {
            logs = logs.Where(s => s.Name.Contains(searchString));
        }

        if (!String.IsNullOrEmpty(parentComment))
        {
            logs = logs.Where(x => x.Type == parentComment);
        }
        Dates = new SelectList(await dateQuery.Distinct().ToListAsync());
        Log = await logs.ToListAsync();
    }

查看

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Log[0].Date)
            </th>
            <th>
            <a asp-action="Index" asp-route-sortOrder='@ViewData["NameSortParm"]'>
                @Html.DisplayNameFor(model => model.Log[0].Name)
            </a>
        </th>
            <th>
                @Html.DisplayNameFor(model => model.Log[0].Relation)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Log[0].Type)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Log[0].Comment)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Log)
        {
            <tr>
                <th>
                    @Html.DisplayFor(modelItem => item.Date)
                </th>
                <td>
                    @Html.DisplayFor(modelItem => item.Name)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Relation)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Type)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Comment)
                </td>
                <td>
                    <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                    <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                    <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

如您所见,我在视图的名称列中对其进行了设置。当我单击它时,URL发生更改,以通知我Index()方法已触发(https://localhost:5001/HSLogs?action=Index)并且页面重新加载。没有排序发生。几乎什么都没有发生。有想法吗?

2 个答案:

答案 0 :(得分:0)

陈雪丽的建议奏效了。谢谢。

我摆脱了控制器中的Task<T> Index方法。我将switch语句移至Task OnGetAsync()方法并更新了语法。

控制器:

public string NameSort { get; set; }
public string DateSort { get; set; }    

public async Task OnGetAsync(string sortOrder)
    {
        NameSort = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
        DateSort = sortOrder == "Date" ? "date_desc" : "Date";

        IQueryable<Log> logsEntry = from s in _context.Log
                                        select s;
        switch (sortOrder)
        {
            case "name_desc":
                logsEntry = logsEntry.OrderByDescending(l => l.Name);
                break;
            case "Date":
                logsEntry = logsEntry.OrderBy(l => l.Date);
                break;
            case "date_desc":
                logsEntry = logsEntry.OrderByDescending(l => l.Date);
                break;
            default:
                logsEntry = logsEntry.OrderBy(l => l.Date);
                break;
        }

        Log = await logsEntry.AsNoTracking().ToListAsync();
    }

在视图中,我使用“日期”列和“名称”列的相应标记帮助器更新了标题链接。

查看

<table class="table">
    <thead>
        <tr>
            <th>
                <a asp-page="./Index" asp-route-sortOrder="@Model.DateSort">
                    @Html.DisplayNameFor(model => model.Log[0].Date)
                </a>
            </th>
            <th>
                <a asp-page="./Index" asp-route-sortOrder="@Model.NameSort">
                    @Html.DisplayNameFor(model => model.Log[0].Name)
                </a>
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Log[0].Relation)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Log[0].Type)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Log[0].Comment)
            </th>
            <th></th>
        </tr>
    </thead>
         ...
</table>

答案 1 :(得分:0)

一种在Asp.net core 5.0上进行排序的简单可重用的方法

public async Task<IActionResult> Index(Query query)
{
   var models = await _context.model.AsQueryable();

   var columnName = new Dictionary<string, Expression<Func<Model, object>>>()
   {
      ["name"] = m => m.name,
      ["date"] = m => m.date
   } 

   models = query.IsSortByAscending 
         ? models.SortBy(columnName[query.SortBy])
         : models.OrderByDescending(columnName[query.SortBy])
}

如果要添加更多列进行排序,只需在列中添加列名作为键,并添加其值(以lamba表达式的形式)。