IAQuery: consultas dinámicas sin informe
Referencia de IAQuery en el SDK .NET: campos, operadores, funciones de agregación y fecha, límites del servidor y formato de la respuesta.
IAQuery ejecuta una consulta definida en la propia llamada: eliges campos, filtros, agrupación y orden, el servidor genera el SQL y lo ejecuta en la base de datos. No necesitas crear un informe en Flex.
// Total facturado desde enero, calculado en el servidor
var req = new IAQueryRequestParameters(VentasIngresosD._SectionID, 1);
req.AddField(VentasIngresosD.VentasIngresosES.ImporteTotal, "sum", "total");
req.AddWhere(VentasIngresosD.VentasIngresosES.FechaOperacion, ">=", "2026-01-01");
var res = await dinaupClient.IAQuery_GetAsync(req);
var total = res.Data[0]["total"];La agregación corre en la base de datos: sumar 800.000 facturas devuelve una fila, no 800.000. Las constantes de sección y campo (VentasIngresosD) salen de tu paquete MyDinaup; también puedes pasar el GUID de la sección y las claves de campo en crudo.
Cuándo usar IAQuery
| Necesidad | Herramienta |
|---|---|
| Listado estable, con columnas cuidadas y reutilizable | Informe de Flex |
| Agregado o consulta puntual definida en código | IAQuery |
| Volcar un informe entero para exportar o sincronizar | LoadAllRowsAsync |
| Leer datos desde otro lenguaje, por REST | Informes por API |
IAQuery no está en la API REST pública: hoy se usa desde el SDK .NET o desde el playground de play (abajo).
¿Un panel o una gráfica? DinaZen trae DnzDynamicStat: recibe el resultado de una consulta y elige KPI, gráfico o tabla según la forma del dato.
Construir la consulta
IAQueryRequestParameters se monta con métodos encadenables:
| Método | Qué añade |
|---|---|
AddField(campo, funcion, alias) | Columna del SELECT. funcion y alias son opcionales |
AddWhere(campo, op, valor, logico) | Condición de filtro. logico: and (por defecto) u or |
AddGroupBy(campo, funcion) | Agrupación, con función de fecha opcional |
AddOrderBy(campo, direccion) | Orden asc o desc |
AddHaving(campo, op, valor, logico) | Filtro sobre los agregados, misma sintaxis que el WHERE |
Limite y Pagina completan la petición. Ejemplo completo, ventas de 2026 por mes:
using static DemoUp.MyDinaup.SectionsD; // constantes de tu MyDinaup
var req = new IAQueryRequestParameters(VentasIngresosD._SectionID, 12);
req.AddField(VentasIngresosD.VentasIngresosES.FechaOperacion, "monthyear", "mes");
req.AddField(VentasIngresosD.VentasIngresosES.ImporteTotal, "sum", "total");
req.AddGroupBy(VentasIngresosD.VentasIngresosES.FechaOperacion, "monthyear");
req.AddWhere(VentasIngresosD.VentasIngresosES.FechaOperacion, ">=", "2026-01-01");
req.AddWhere(VentasIngresosD.VentasIngresosES.FechaOperacion, "<=", "2026-12-31");
req.AddOrderBy(VentasIngresosD.VentasIngresosES.FechaOperacion, "asc");
var res = await dinaupClient.IAQuery_GetAsync(req);
foreach (var fila in res.Data)
Console.WriteLine($"{fila["mes"]}: {fila["total"]}");Todo campo tiene además un alias por defecto: el último tramo de su ruta. Para claves internas (pr_...) conviene declarar un alias legible, como "total".
Funciones de campo
Se aplican en AddField y, las de fecha, también en AddGroupBy.
Agregación:
| Función | Devuelve |
|---|---|
sum | Suma (0 si no hay filas) |
count | Cuenta de valores del campo |
count* | Cuenta de filas |
countdistinct | Cuenta de valores distintos |
avg | Media (0 si no hay filas) |
min / max | Mínimo y máximo |
Fecha (transforman un campo de fecha en texto, útiles para agrupar):
| Función | Ejemplo de salida |
|---|---|
date | 2026-07-09 |
month | 07 |
year | 2026 |
monthyear | 07/2026 |
quarter | 3T |
quarteryear | 3T - 2026 |
dayofweek | 1 a 7 (1 = lunes) |
dayofmonth | 09 |
hour | 00 a 23 |
Cualquier otra función se rechaza con un error que lista las admitidas.
Filtros
Operadores admitidos en AddWhere y AddHaving (en minúsculas):
| Operador | Nota |
|---|---|
= <> > < >= <= | Comparación directa |
like / not like | Incluye tú los comodines: %texto% |
in / not in | Valores separados por comas: "a,b,c" |
is null / is not null | Sin valor |
Los valores viajan como texto: fechas en ISO (2026-01-31), números con punto decimal, booleanos como 1 y 0. Cada campo se valida contra el esquema y los operadores van con lista blanca; los valores se escapan en el servidor.
Los registros eliminados quedan fuera de toda consulta: el servidor añade eliminado = 0 por ti. Si quieres verlos, incluye tu propia condición sobre el campo eliminado.
Ordenar y paginar
AddOrderBysolo acepta campos que estén en el SELECT, con un máximo de 5 criterios, direcciónascodescy sin repetir campo.- Sin
AddOrderBy, las consultas no agregadas llegan por fecha descendente. Las agregadas llegan sin orden garantizado: pide el tuyo. Limiteadmite de 1 a 30.000 filas por página (100 si no lo indicas). Para leer más filas, pagina.Paginaempieza en 1, no en 0.- El
Totalde la respuesta son las filas devueltas en esa página, no las que existen en la sección.
El SDK valida la petición antes de enviarla, así que estos errores no gastan una llamada al servidor:
| Qué haces mal | Qué te lanza |
|---|---|
Limite fuera de 1..30.000 | ArgumentOutOfRangeException |
Pagina menor que 1 | ArgumentOutOfRangeException |
| Sección, campo u operador vacíos | ArgumentException |
logico distinto de and/or, dirección distinta de asc/desc, campo repetido en el orden | ArgumentException |
| Más de 5 criterios de orden | InvalidOperationException |
Ejecutar sin ningún AddField, u ordenar por un campo que no está en el SELECT | InvalidOperationException |
Campos de secciones relacionadas
Un campo de referencia guarda el GUID del registro relacionado. Para leer un campo de la sección relacionada (su nombre, por ejemplo), usa una ruta de cuatro tramos:
seccionID.campoReferencia.seccionRelacionadaID.campoCon ella puedes agrupar ventas por nombre de cliente sin resolver GUIDs a mano. El playground de play construye estas rutas por ti al elegir el campo relacionado.
La respuesta
IAQuery_GetAsync devuelve un IAQueryResponse:
| Campo | Contenido |
|---|---|
Ok | true si la consulta se ejecutó |
Columns | Alias de las columnas, en el orden del SELECT |
Data | Filas como List<Dictionary<string, string>>: clave alias, valor texto |
Total | Filas devueltas en esta página |
Page / Limit | Página y límite aplicados |
TimeMs | Milisegundos de ejecución en el servidor |
SQL | El SQL exacto que se ejecutó |
ErrorNotices / Description | Detalle del error cuando Ok es false |
Todos los valores llegan como texto: conviértelos a su tipo al leerlos. El campo SQL te deja verificar la consulta generada mientras desarrollas.
Atajos: QuickQuery
Para las preguntas de siempre (contar, sumar, agrupar) no hace falta construir la petición. El cliente expone QuickQuery, que devuelve el valor ya convertido:
// Suma (decimal) y cuenta (int), sin leer Data ni convertir a mano
var total = await dinaupClient.QuickQuery.SumAsync(VentasIngresosD._SectionID, VentasIngresosD.VentasIngresosES.ImporteTotal);
var n = await dinaupClient.QuickQuery.CountAsync(VentasIngresosD._SectionID);Los seis métodos, sus filtros y el formato del resultado, en QuickQuery.
Permisos y validación
- La consulta hereda los permisos del usuario de la sesión: se validan contra el informe principal de la sección. Sin permiso de consulta, la llamada se rechaza.
- Las secciones base no se consultan directamente; consulta la sección concreta.
- Campos nativos disponibles en toda sección:
id,nombre,fecha,eliminado.
Pruébalo sin código
En play, la app Desarrolladores incluye el playground de IAQuery (Consulta con IA, en Herramientas). Eliges sección, campos, filtros, agrupación y orden en un editor visual, y ves las filas, el tiempo y el SQL generado. Lo que montas ahí se traduce línea a línea a los métodos de esta página.
Para el resto de la API del cliente (informes, escrituras, sesión), ver el Cliente Dinaup.
Listados de alto rendimiento
Vuelca un informe entero sin OFFSET con LoadAllRowsAsync: paginación por keyset, coste constante por página y sin filas repetidas.
QuickQuery: contar, sumar y agrupar en una línea
Referencia de QuickQuery en el SDK .NET: seis métodos sobre IAQuery para contar, sumar, agrupar y consultar secciones con valores ya convertidos.