【发布时间】:2014-01-05 15:14:03
【问题描述】:
我在犹豫如何显示搜索结果。
情况如下: 我有一个网站,用户可以在其中填写几个 texbox 并在此基础上执行搜索。然后我想以分页的方式向他展示结果:类似于:
照片、姓名、年龄 |照片、姓名、年龄 |照片,姓名年龄
所以我希望有 3 列,然后可能有 5 行。
但我不知道,什么是表示这种东西的最佳方式,有没有最好的方法等?
提前致谢
【问题讨论】:
标签: c# asp.net-mvc-3
我在犹豫如何显示搜索结果。
情况如下: 我有一个网站,用户可以在其中填写几个 texbox 并在此基础上执行搜索。然后我想以分页的方式向他展示结果:类似于:
照片、姓名、年龄 |照片、姓名、年龄 |照片,姓名年龄
所以我希望有 3 列,然后可能有 5 行。
但我不知道,什么是表示这种东西的最佳方式,有没有最好的方法等?
提前致谢
【问题讨论】:
标签: c# asp.net-mvc-3
嗯,您可以从许多不同的角度采用多种方法。我们真的可以谈论它很久了。但是,简而言之,您可以在表示层、控制器级别、业务逻辑层或数据层实现分页。基本上,应用程序层越低,您将获得更好的性能,就性能而言,在控制器和业务逻辑层实现分页之间没有太大区别,但设计明智的是最好将这些问题留在业务中逻辑层以获得更好的可维护性和可扩展性。如果在数据层实现分页,您将获得更好的性能,特别是如果您有大量数据要显示,然后告诉数据访问层只获取您的应用程序感兴趣的数据页面。使用其他方法将强制您从后端存储中检索所有数据,这可能会导致不必要的带宽消耗和数据传输。请参阅下面的示例,我在数据层级别进行分页..
我正在使用自定义数据访问层运行下面的 sql 查询来查询大量设备...
select top (@pagesize) *
from
(
select row_number() over(order by d.Name) as RowId
, d.Id
, d.Name
, d.IsDeleted
, dt.Id as DeviceTypeId
, dt.Name as DeviceTypeName
from Devices d
left join DeviceTypes dt on dt.Id = d.DeviceTypeId
)
as o
where o.RowId <= (@page * @pagesize) and o.RowId > ((@page - 1) * @pagesize)
查询很简单,您可以指定页面大小(每个数据页面的记录)和要检索的数据页面(第一页、第二页等)。这个查询由我的数据访问层运行,它构造业务对象并将它们传递给业务逻辑层
然后,在我的业务逻辑中,我调用了设备数据对象来检索我感兴趣的数据页面。下面的方法完成了这项工作......
public IList<DeviceBO> GetAllDevices(int page, out int count)
{
count = DataProvider.Devices.GetAllDevicesCount();
return DataProvider.Devices.GetAllDevices(page, BusinessConstants.GRID_PAGE_SIZE);
}
非常直接的操作。然而,有几件事需要注意。一,我要对数据库进行两次往返;第一个获取所有设备的计数,第二个获取设备的数据页。我们可以争辩说,这可以通过单次访问数据库来避免,但在我的情况下,这是一个非常快速的查询,运行时间不到 1 秒,相信我......我有超过一百万条记录。对GetAllDevicesCount 的调用只不过是一条sql select count(Id) from dbo.Devices
还要注意DataProvider 只是一个工厂对象。你真的不需要担心实现细节。 BusinessConstants.GRID_PAGE_SIZE simple 返回一个数字,这是我的应用程序中使用的标准页面大小(我有一些网格/表格),这只是一种将东西保存在一个地方的方法,以防我想更改所有页面的大小网格/表格稍后。
然后我定义了一个设备控制器,它公开了以下操作方法(管理)...
public class DevicesController : Controller
{
public ActionResult Manage(string currentPage)
{
return process_device_list(currentPage);
}
//this method was created as a result of code re-factoring since it is used in several other action methods not shown here
private ActionResult process_device_list(string currentPage, bool redirect = false)
{
int count = 0;
int page = 1;
if (!int.TryParse(currentPage, out page))
{
if (!string.IsNullOrEmpty(currentPage))
return RedirectToAction("Manage");
page = 1;
}
var model = new DeviceManagementListModel();
model.Devices = BusinessFactory.DevicesLogic.GetAllDevices(page, out count);
model.ActualCount = count;
model.CurrentPage = page;
if (!redirect)
return View(model);
else
return RedirectToAction("Manage", new { @currentPage = currentPage });
}
}
视图几乎只是 HTML 和 razor 语法,没有什么有趣的事情发生。也许,表格/网格的页脚是发生更多有趣事情的地方,因为在那里定义了分页标记....
<tfoot>
<tr>
<td colspan="4">
<div class="pager">
@using (Html.BeginForm("Manage", "Devices", FormMethod.Get)){
@Html.TextBoxFor(x => x.CurrentPage, new { title = "Enter a page number to change the page results" })
<input type="submit" value="Go" title="Change the current page result" />
}
</div>
<div class="total">
@Model.ActualCount record(s) found
</div>
</td>
</tr>
</tfoot>
这就是它的样子……
在我看来,在表格的tfoot 部分中,我添加了一个form 元素,该元素向我的操作方法Manage 发出GET 请求,而不是POST 请求。这对于提供一个不错的 url 很有用,用户可以在其中手动指定他们感兴趣的页面...
我希望它可以帮助你获得一些基本的想法
【讨论】:
Skip 和 Take。如果你想添加任何条件,那么这就是为什么我们在 sql 中有where 子句,只需确保相同的条件与计数查询匹配。够清楚吗?
Skip(PageSize * PageIndex)...假设PageIndex是从零开始的,然后Take(PageSize)....看看这个stackoverflow.com/questions/3870091/…