framework - ASP.NET MVC Webgrid Efficient Paging
paginacion mvc 5 c# (4)
Tengo un proyecto ASP.NET MVC 4 y una vista SQL (vvItem). ItemController
MVCAppEntities db = new MVCAppEntities();
public ActionResult Index()
{
var itemqry = db.vvItem.OrderBy(s => s.name);
//var pageditems = itemqry.Skip(10).Take(20); // 25 seconds
return View(itemqry.ToList()); // 88 seconds
}
Vista Index.cshtml
@model IEnumerable<MVCApplication1.Models.vvItem>
@{
var norows = 20;
var grid = new WebGrid(Model, canPage: true, rowsPerPage: norows);
grid.Pager(WebGridPagerModes.NextPrevious);
@grid.GetHtml(tableStyle: "table", headerStyle: "header", columns: grid.Columns(
grid.Column(columnName: "name", header: "Name", canSort: true),
grid.Column(columnName: "quantity", header: "Quantity", canSort: true),
grid.Column(columnName: "code", header: "Code", canSort: true),
grid.Column(columnName: "Price", header: "Price", canSort: true),
))}
En vvItem tengo casi 400000 registros. Pensé que el Buscapersonas de la redgrid cargaría (Take ()) solo los registros mostrados y sabría Omitir () los primeros registros si fuera a las siguientes páginas.
P : ¿Cómo puedo hacer una vista eficiente para cargar solo los registros mostrados?
Encontré 2 soluciones: versión JSON y NerdDinner
No soy tan bueno en JSON, así que probé la solución NerdDinner. Y como en mi línea comentada //var pageditems = itemqry.Skip(10).Take(20);
itemqry ya está cargado con todos los registros y llevó mucho tiempo cargarlos.
Q2 : ¿cómo puedo hacer paginación ahora? Necesito modificar la página no. del método Index.
public ActionResult Index(int? page, string filter1 = " ", string filter2 = " ")
Gracias por esto.
Modifiqué esto para trabajar con algunos parámetros de entrada en mi SP para controlar el tamaño de página, el número de página, el índice de clasificación y el orden de clasificación:
declare @sql nvarchar(1000) = ''
select * from
(
select *, row_number() over(order by ''+@SortIndex+'' ''+@SortOrder+'') as RowNumber from #Results
) as T
where T.RowNumber between (''+@PageNumber+'' - 1) * ''+@PageSize+'' + 1 and ''+@PageNumber+'' * ''+@PageSize
exec sp_executesql @sql
Hice un procedimiento almacenado de SQL
CREATE PROCEDURE SkipTake
@pagNo int,
@pageSize int
AS
select *
from (select *, row_number() over (order by COD) as rn
from vvSTOC
) as T
where T.rn between (@pagNo - 1) * @pageSize + 1 and @pagNo * @pageSize
He agregado esta sp en mi modelo EF en Importación de funciones para que devuelva una entidad (vvSTOC)
public ActionResult Index(int? page)
{
const int pageSize = 20;
return View(db.spSkipTake(page, pageSize).ToList());
}
No debería ejecutar la consulta de inmediato, siempre que itemqry sea un tipo IEnumerable o IQueryable. ¿Puedes lanzarlo como IQueryable de la siguiente manera?
public ActionResult Index()
{
IQueryable<vvItem> itemQry = db.vvItem;
return View(itemQry.OrderBy(s => s.name).Skip(10).Take(20).ToList());
}
Si itemqry es el tipo correcto, no se ejecutará hasta que se llame a .ToList (), que lo convierte en un tipo IList. Verifique el SQL que se está produciendo para estar seguro.
public ActionResult Index(int? pageIndex)
{
int pageSize = 20;
var itemIndex = ((pageIndex??1) -1) * pageSize;
return View(db.vvItem.OrderBy(s => s.name).Skip(itemIndex).Take(pageSize).ToList());
}