LoadAllRowsAsync
LoadAllRowsAsync recorre un informe completo por keyset sobre el id, sin OFFSET, con coste constante por página y sin filas repetidas ni saltadas.
Cuando necesitas todas las filas de un informe (exportar, reprocesar, sincronizar), la forma de paginar decide el rendimiento y la corrección. LoadAllRowsAsync, en DinaupReportBase, recorre el informe completo por keyset sobre el id, sin OFFSET.
Antes de empezar
- Un informe tipado de tu MyDinaup y un
DinaupClientCconectado. Ver Cliente Dinaup. - El informe tiene que exponer la columna
ID. Los informes generados por MyDinaup la traen.
El problema de OFFSET
La forma clásica de recorrer un informe página a página usa LIMIT y OFFSET: pide la página N hasta que una vuelva corta.
var report = new APISeccionDePruebasAPIC();
var filas = new List<APISeccionDePruebasAPIC.APISeccionDePruebasAPI_RowC>();
for (int pagina = 1; ; pagina++)
{
await report.ExecuteQueryAsync(dinaupClient, pagina, pageSize);
filas.AddRange(report.Rows);
if (report.Rows.Count < pageSize) break;
}No uses ExecuteQuery_NextPageAsync() para esto. Ese método decide si hay página siguiente con el recuento del servidor, que sobre un filtro caro no termina a tiempo: el recorrido se queda en la primera página. Detalle en Cliente Dinaup.
En volúmenes grandes, OFFSET tiene dos problemas:
- Corrección.
OFFSETsin un orden total y sin desempate no es determinista: el servidor devuelve la misma fila en dos páginas o se salta una. Si después indexas por id, obtienes una excepción de clave duplicada o filas que faltan sin aviso. - Rendimiento.
OFFSET 18000obliga al servidor a recorrer y descartar 18.000 filas en cada página. Cuanto más avanzas, más lento va.
Paginación por keyset
En vez de pedir la página N, pides las filas posteriores al último id que viste:
WHERE id > :last_seen_id
ORDER BY id ASC
LIMIT :page_sizeCada página es un recorrido por rango de índice sobre la columna id: coste constante sin importar la profundidad y, como el id es único, ninguna fila repetida ni ningún hueco.
Cómo se usa
var todas = await report.LoadAllRowsAsync(dinaupClient, pageSize: 10000, adminMode: true);Firma y valores por defecto:
Task<List<T>> LoadAllRowsAsync(
DinaupClientC dinaupClient,
int pageSize = 10000,
int maxRows = 50000000,
bool adminMode = false)El método:
- Ordena por la columna
IDdel informe (AddOrder(colId, false)). No llames aAddOrderantes: lanza excepción si ya hay un orden definido. - Añade un único filtro
id > cursory lo avanza tras cada página, así que tus filtros (rangos de fecha, referencias) se conservan y se combinan conAND. - Pide siempre la página 1 con
pageSizefilas y para cuando una página vuelve más corta o el cursor no avanza. - No pide el recuento al servidor (
RequestParams.GetPageSummary = false), así que no depende de él. - Si llega a
maxRowscon filas pendientes, lanza excepción en vez de devolver una lista truncada en silencio: reduce el informe con un filtro o subemaxRows.
Otro orden
El keyset ordena por id, así que aplica el orden de presentación en memoria después:
var porFecha = todas.OrderBy(r => r.Fecha).ToList();Límites y excepciones
LoadAllRowsAsync lanza excepción cuando no puede garantizar un recorrido correcto:
| Condición | Excepción |
|---|---|
pageSize o maxRows no positivos | ArgumentException |
El informe no expone columna ID | InvalidOperationException |
Ya se llamó a AddOrder | InvalidOperationException |
Ya hay un filtro sobre la columna ID | InvalidOperationException |
Las filas no implementan IDinaupRow | InvalidOperationException |
Se alcanza maxRows con filas pendientes | InvalidOperationException |
Cuándo usar cada uno
ExecuteQueryAsync por páginas (OFFSET) | LoadAllRowsAsync (keyset) | |
|---|---|---|
| Una página visible | la opción correcta | excesivo |
| Volcar el informe entero | duplicados y huecos posibles, se ralentiza | correcto y de coste constante |
| Orden de presentación durante la paginación | en el servidor | en memoria tras cargar |
Para volúmenes que se leen a diario, la réplica SQL de PG Sync evita pasar por la API. Para exportar una sección entera a un CSV sin pasar por un informe, usa ExportAsync, en Cliente Dinaup. El resto de la API de informes (filtros, paginación clásica, tiempos del servidor) está en Cliente Dinaup.