Imaginemos por un instante un simple modelo de datos que sirva a gestionar una jerarquía con inmediatos n descendientes. Por ejemplo, un libro de recetas e ingredientes, órdenes de compra, proyectos y actividades. Padres e hijos. Datos que para visualizarlos en Power Apps se podría simplemente crear una Gallery por ejemplo con las recetas y dentro de ella crear otra Gallery que filtre sus items cuando receta_id es igual a ThisItem.id. Esta configuración obligará a Power Apps a realizar una consulta sobre la tabla de ingredientes para cada receta, lo que seguramente desde un punto de vista de las prestaciones no es lo mejor del mundo. Además, si quisiéramos filtrar la Gallery a través de un campo de texto, no podríamos filtrar recetas por ingredientes ya que los items de la Gallery está compuesta por la table receta.
Si pudiéramos incluir recetas y todos los ingredientes dentro una vista el problema estaría resuelto. Lamentablemente, si creáramos una vista con un simple LEFT JOIN las columnas de cada receta se repetirían n veces cuantos ingredientes cuente. Un desastre para el usuario.
Gracias al recién llegado ParseJSON (aún función experimental, pero que seguro llegó para quedarse) sería posible decodificar una columna de nuestra vista que devuelva todos los ingredientes agrupados en JSON (ver FOR JSON).
El primer paso es crear la vista en SQL. Para devolver hijos agrupados en formato JSON utilizaremos FOR JSON
Aplique formato JSON a los resultados de las consultas o exporte datos de SQL Server como JSON mediante la adición de la cláusula FOR JSON a una instrucción SELECT. Use la cláusula FOR JSON para simplificar las aplicaciones cliente mediante la delegación del formato de la salida JSON desde la aplicación a SQL Server.
La consulta debería ser más o menos así:
CREATE VIEW [schema].[receta_detalles]
AS
SELECT
r.*,
(
SELECT
*
FROM
receta_ingredientes
WHERE
receta_id = r.id FOR JSON PATH) AS ingredientes
FROM
receta
Ahora que temenos nuestra vista con la columna ingredientes en formato JSON vamos a crear en Power Apps una Gallery con la vista receta_detalles en la propiedad items. Luego, vamos a crear otra Gallery dentro la primera donde vamos a convertir el JSON de la columna ingredientes en una tabla. Previamente, será necesario (por lo menos al momento de este artículo) habilitar la función experimental ParseJSON.
El Código del parámetro items debería verse más o menos así:
SortByColumns(
ForAll(
Table(ParseJSON(ThisItem.ingredientes)),
{
ingrediente: Text(Value.ingrediente),
cantidad: Value(Value.cantidad),
depth: Value(Value.depth)
}
),
"depth",
Ascending
)
De este modo hemos evitado a Power Apps el echo de tener que realizar una consulta a SQL sobre los igredientes de cada receta. Todo con una sola llamada.
Otro beneficio de esta solución es que teniendo todos los datos en una única vista será muy simple realizar una búsqueda de todas las recetas que contengan x ingrediente. Será suficiente crear un campo de texto y en la propiedad items de la Gallery raíz escribir:
SortByColumns(
Search(
Filter(
'schema.receta_detalles,
Or(
created_by = cmbRecetaCreatedFilter.Selected.id,
IsBlank(cmbRecetaCreatedFilter.Selected.id)
)
),
txtRecetaFilter.Text,
"ingredientes"
),
"created",
Descending
)