INSTITUCIONAL
COMUNIDAD
BLOG
AYUDA
MI CUENTA
EN PT ES

ht dt 286

How to: Ejemplos de Data Providers con condiciones

(16/02/2009-17:04)
El uso de “condiciones” en los data providers permite darle mayor potencia expresiva a los mismos y así brindar una solución versátil para distintos tipos de “output".
En GeneXus X hemos incorporado el nuevo tipo de objeto Data Provider. A modo de pequeña introducción para aquellos que aún no lo conozcan, los Data Providers son un objeto declarativo que sustituye a una determinada clase de procedimientos: aquellos que reciben una entrada, realizan un proceso y su objetivo final es devolver un conjunto de datos en un formato estructurado, o sea el foco esta puesto en la salida.

De este modo se define el formato de la salida del Data Provider y eso lo transforma en un objeto más declarativo que un procedimiento pues pone el énfasis en “qué hacer” en lugar de “cómo hacerlo”

Los componentes básicos de los Data Providers son los Grupos, Elementos, Variables, Subgrupos y opciones avanzadas de control para los Grupos (Defaul clause, Paginate clause, NoOutput clause, OutputIfDetail clause e Input clause).

Más detalles en el CommunityWiki 

El objetivo de este How to es mostrar dos ejemplos de uso interesantes.

El primero a efectos de mostrar que en las condiciones Where de los grupos no sólo puedo agregar condiciones donde el lado izquierdo de la comparación sea un atributo sino también pueden ser variables.

Supongamos que queremos obtener una lista de empleados con sus datos, este sería el Data Provider:

EmployeeCollection
{
       EmployeeItem
      {
                    Id = EmployeeId
                    Name = EmployeeDsc
                    Address = EmployeeAddress
       }
}

Ahora, si tuvieramos la necesidad de condicionar la salida dependiendo de si el usuario está autorizado a ver esa información o no, podría agregar la siguiente condición:

EmployeeCollection
{
             EmployeeItem
             Where &UsrAut=”S” 
             {
                        Id = EmployeeId
                        Name = EmployeeDsc
                        Address = EmployeeAddress
              }
}

 En este caso se agrega el filtro a la sentencia SQL generada, la cual sería la siguiente:

SELECT [EmployeeId], [EmployeeDsc], [EmployeeAddress] FROM [Employee] WITH (NOLOCK)
WHERE @AV1UsrAut = “S” ORDER BY [EmployeeId]

Incluso si quisiera devolver siempre los datos, pero solamente mostrar la dirección para aquellos usuarios autorizados, podría hacer lo siguiente:

EmployeeCollection
{
           EmployeeItem
          {
                  EmployeeId
                  EmployeeDsc
                  EmployeeAddress [NoOutput]
                  Where &UsrAut=”S”
                  {
                            EmployeeAddress = EmployeeAddress;
                            EmployeeSalary = EmployeeSalary;
                   }
           }
}
 
En este caso se genera la sentencia select pero sin la condición de filtro, la cual se transforma en un IF en el fuente del Data Provider :

Select a ejecutar:
SELECT [EmployeeId], [EmployeeDsc], [EmployeeAddress], [EmployeeSalary]
FROM [Employee] WITH (NOLOCK) ORDER BY [EmployeeId]

Y además en el fuente del DP:
if ( AV1UsrAut = “S”)
{
Gxm1employee.gxTpr_Employeeaddress = A363Employee ;
Gxm1employee.gxTpr_Employeesalary = A364Employee ;
}

Nota: si en lugar de un grupo de atributos (Adress, Salary, etc) se quiere filtrar solo un valor se puede escribir directamente:
EmployeeAddress = EmployeeAddress if &UsrAut=”S”;

Veamos otro ejemplo interesante:

Supongamos en este ejemplo que tenemos una aplicación que maneja Clientes y Prospects (los Clientes están en una tabla y los Prospects en otra). Se quiere escribir un Data Provider el cual devolverá una Collection que contenga los Clientes o Prospects Activos.

El Data Providers recibirá como parámetro si se quieren ver Clientes o Prospects:

Una forma de escribirlo es la siguiente:

Parm(&FiltrarPor)
 
SDTCliProsCollection
{
          SDTCliProsCollectionItem using DSClientesActivos()
          where &FiltrarPor = ‘CLIENTE’
          {
                   PartnerId = ClienteId
                   PartnerName = ClienteName
          }
          SDTCliProsCollectionItem using DSProspectsActivos()
          where &FiltrarPor = ‘PROSPECT’
          {
                   PartnerId = ProspectId
                   PartnerName = ProspectName
          }
}

DSClientesActivos define el filtro sobre Clientes y DSProspectsActivos hace lo análogo pero en la tabla de Prospects.
Notar que esto ejecutara siempre los dos selects pero agregara al where el valor de &FiltrarPor recibido como parámetro por el Data Providers (por lo tanto uno devolverá datos y el otro no).

Esto genera:

SELECT [ClienteTipo], [ClienteId], [ClienteNombre] FROM [Cliente] WITH (NOLOCK)
WHERE (@AV4Filtrar = 'CLIENTE') AND ([ClienteStatus] = “Activo”) ORDER BY [ClienteId]

SELECT [ProspectTipo], [ProspectId], [ProspectNombre] FROM [Prospect] WITH (NOLOCK)
WHERE (@AV4Filtrar = 'PROSPECT') AND ([ProspectStatus] = “Activo”) ORDER BY [ProspectId]

Sin embargo podemos escribir el Data Provider como sigue, para que no ejecute siempre los dos selects, sino solamente el que corresponde de acuerdo al parámetro &FiltrarPor (es en el fuente generado donde se decide que select ejecutar).

SDTCliProsCollection
{
          SDTCliProsCollectionDummy [NoOutput]
          where &FiltrarPor = 'CLIENTE'
          {
                   SDTCliProsCollectionItem using DSClientesActivos()
                   {
                             PartnerId = ClienteId
                             PartnerName = ClienteNombre
                   }
          }
          SDTCliProsCollectionDummy [NoOutput]
          where &FiltrarPor = 'PROSPECT'
          {
                   SDTCliProsCollectionItem using DSProspectActivos()
                   {
                             PartnerId = ProspectId
                             PartnerName = ProspectNombre
                   }
          }

}

Select a ejecutar en caso de invocar al DP con &FiltrarPor = ‘CLIENTE’:
SELECT [ClienteTipo], [ClienteId], [ClienteNombre] FROM [Cliente] WITH (NOLOCK) WHERE [ClienteStatus] = “Activo”
ORDER BY [ClienteId]
 
Y además en el fuente del Data Providers:
 
         if ( ( String.CompareOrdinal(AV4Filtrar.TrimEnd(' '), "CLIENTE".TrimEnd(' ') ) == 0 ) )
         {
            AV10DSClie = AV2Cliente ;
            /* Using cursor P001R2 */
            pr_default.execute(0, new Object[] {AV10DSClie});
            while ( (pr_default.getStatus(0) != 101) )
            {
               ………………………. (select con filtro por [ClienteStatus] = “Activo”)
            }
            pr_default.close(0);
         }
         if ( ( String.CompareOrdinal(AV4Filtrar.TrimEnd(' '), "PROSPECT".TrimEnd(' ') ) == 0 ) )
         {
            AV12DSPros = AV3Prospec ;
            /* Using cursor P001R3 */
            pr_default.execute(1, new Object[] {AV12DSPros});
            while ( (pr_default.getStatus(1) != 101) )
            {
               ……………………….(select con filtro por [ProspectStatus] = “Activo”)
            }
            pr_default.close(1);
         }

 

         this.cleanup();
Relacionado
How to: Data Providers
GeneXus X incrementa la productividad de desarrollo con Data Providers y Data Selector
How to: Workflow
Data Providers y Business Components para inicializar datos
How to: GXflow en GeneXus X Evolution 1
How to: Cómo habilitar la seguridad en GXserver
GeneXus Training Uruguay publicó su calendario de capacitación para el primer semestre del año
Uruguay centraliza toda la información sobre comercio exterior e inversiones en Siicex, un portal desarrollado en GXportal y GeneXus
Curso de Seguridad en aplicaciones GeneXus
Certificaciones #GeneXus en el #GX24
GeneXus X Evolution 3 Upgrade 2 Preview 3
GXquery 4.0 Upgrade 3 ¡Liberado!
LightCRM App para Windows Phone, Android e iOS desarrollada con GeneXus X Evolution 3 ¿La probaste?
¡919 certificados GeneXus! #GeneXusLoMejorDe2014
¡64 novedades en GeneXus MarketPlace!#GeneXusLoMejorDe2014