2012-04-13 40 views
9

¿Hay alguna forma de obtener el recuento de filas de una consulta compleja Linq y millones de registros sin pulsando dos veces el db o escribiendo 2 consultas separadas?C# Entity Framework Pagination

Podría tener mi propia sugerencia. Escribe un procedimiento almacenado, pero estoy bien con MySQL no con MSSQL.

Cualquier sugerencia mejor sería genial. Además, si alguien sabe si Microsoft está trabajando para agregar esta característica al marco de la entidad.

+3

Estoy bastante seguro de que no puede obtener el número de filas en su consulta sin tocar la base de datos o escribir una consulta separada de la que realmente devuelve esas filas. –

+0

¡Gracias @JonathanWood por tus pensamientos! –

+1

Cuando utiliza .Count() en EF, no selecciona todas las filas, solo ejecuta una instrucción 'select count() from table' sql, por lo tanto, si necesita 2 consultas, una de ellas es muy económica. –

Respuesta

2

La forma más común de mostrar millones de registros es simplemente no mostrar todas las páginas. Piénselo: si tiene millones de registros, digamos 20 o incluso 100 artículos por página, tendrá decenas de miles de páginas. No tiene sentido mostrarlos todos. Simplemente puede cargar la página actual y proporcionar un enlace a la página siguiente, eso es todo. O puede cargar, digamos, 100-500 registros, pero aún mostrar solo una página y usar la información de registros cargados para generar enlaces de página para las primeras páginas (para saber con seguridad cuántas páginas siguientes están disponibles).

+0

Tiene razón, no quisiera mostrar cientos o miles de enlaces o incluso hacer que alguien revise esas páginas. Creo que el problema que tengo es que quiero escribir solo una consulta.Por ejemplo: MySQL le permitió usar SQL_CALC_FOUND_ROWS dentro de una consulta y luego otra consulta para obtener ese resultado. ¡¡¡Muy eficiente!!! ¡Paginación maravillosa! Gracias @VladimirPerevalov por tus pensamientos! –

+0

AFAIK no existe tal soporte en LINQ ni en MS SQL Server. En realidad, hay muchas cosas que hace MySql y MS SQL no. P.ej. 'SELECT BETWEEN ...' también es muy efectivo para la paginación. –

+0

también puede proporcionar un cuadro de texto "Ir a:" y un botón para ir directamente a una página específica. –

8

Sugeriría usar la función Take(). Esto se puede usar para especificar la cantidad de registros a tomar de una consulta o lista de linq. Por ejemplo

List<customers> _customers = (from a in db.customers select a).ToList(); 
var _dataToWebPage = _customers.Take(50); 

utilizo una técnica similar en una aplicación MVC donde escribo la lista _customers a la sesión y luego utilizar esta lista para nuevas consultas de paginación cuando el usuario hace clic en la página 2, 3, etc. Esto ahorra múltiple hits de la base de datos Sin embargo, si su lista es muy grande y luego escribirla, la sesión probablemente no sea una buena idea.

Para la paginación puede usar la función Saltar() y Tomar() juntas. Por ejemplo, para obtener la página 2 de los datos:

var _dataToWebPage = _customers.Skip(50).Take(50); 
+0

Gracias @TimNewton. Por supuesto, pero si tengo un millón de registros o, mejor aún, mil registros con columnas de datos muy grandes, se encontrará con una excepción de falta de memoria. –

+0

Jason, podría considerar escribir las claves principales de una lista en la sesión en lugar de todo el objeto, y luego recuperar los detalles de la base de datos cada vez que necesita volver a mostrar los datos utilizando las claves principales de la lista. Esto aún requiere múltiples lecturas de bases de datos. No creo que pueda escaparse sin múltiples lecturas de db si el conjunto de datos es tan grande. –

+0

es posible que tenga razón acerca de no poder hacer una lectura de base de datos para esta instancia en C# y utilizando Linq. Sé que esto se puede hacer, es solo que quiero la capacidad de usar Linq porque está fuertemente tipado y va con el resto de mi código de limpieza. Tengo la paginación funcionando perfectamente en tablas más pequeñas que no contienen grandes conjuntos de datos o grandes cantidades de datos. –

2

es muy fácil en el servidor sql. puede escribir la siguiente consulta:

select count() over(), table.* from table 

el conteo() sobre el() devolverá el conteo del total de la fila en el resultado, por lo que no tenga que ejecutar dos consultas .. Recuerde que se debe ejecutar en bruto sql en su contexto o utilice dapper que devuelva resultado como ver modelo