Este es el sitio web histórico de la documentación de 4D. La documentación se está trasladando progresivamente a developer.4d.com

Inicio

 
4D v19
Selección de entidades

Selección de entidades  


 

Una selección de entidades es un objeto que contiene una o más referencias a entidades que pertenecen a la misma dataclass. Una entity selection puede contener 0, 1 o entidades X de la dataclass, donde X puede representar la cantidad total de entidades contenidas en la dataclass.

Las selecciones de entidades pueden ser:

  • "compartibles" o "modificables",
  • "ordenadas" o "no ordenadas".

Estos puntos se analizan a continuación. 

Las selecciones de entidades generalmente se crean utilizando una búsqueda o se devuelven desde un atributo relación. Por ejemplo:

 brokers:=ds.Person.query("personType = broker")

Este código devuelve en brokers a todas las personas de tipo broker. Para acceder a una entidad de la selección, utilice una sintaxis similar para acceder a un elemento en una colección. Por ejemplo:

 theBroker:=brokers[0]  //Las selecciones de entidades están basadas en 0

El método entitySelection.orderBy( ) devuelve una nueva selección de entidades de acuerdo con los criterios de clasificación suministrados. Por ejemplo:

 brokers:=brokers.orderBy("name") //devuelve una selección ordenada

Este código devuelve en brokers la misma selección de entidades de las entidades Person, pero ordenadas por nombre.

Alternativamente, puede utilizar un atributo relación para devolver una selección de entidades. Por ejemplo:

 brokers:=ds.Person.query("personType = broker")
 brokerCompanies:=brokers.myCompany

Este código asigna a brokerCompanies todas las empresas relacionadas de las personas en la selección de entidades brokers, utilizando el atributo de relación myCompany. El uso de atributos de relación en las selecciones de entidades es una forma poderosa y fácil de navegar hacia arriba y hacia abajo de la cadena de entidades relacionadas.

Para realizar acciones repetidas en entidades en una selección de entidades, como recuperar y modificar valores de ciertos atributos, puede utilizar la estructura For each...End for each. Por ejemplo:

 C_OBJECT(emp)
 For each(emp;ds.Employees.all())
    If(emp.Country="UK")
       emp.salary:=emp.salary*1,03
       emp.save()
    End if
 End for each

Puede crear un objeto de tipo selección de entidades de la siguiente manera:

Puede crear y usar simultáneamente tantas selecciones de entidades diferentes como desee para una dataclass.

Tenga en cuenta que una selección de entidades solo contiene referencias a entidades. Las selecciones de entidades diferentes pueden contener referencias a las mismas entidades.

Nota: una selección de entidades puede utilizarse en diferentes procesos si es compartible. Para más información, ver el párrafo Selecciones de entidades compartibles vs. modificables abajo.

Todos los atributos de almacenamiento (texto, número, booleano, fecha) están disponibles como propiedades de las selecciones de entidades así como también de las entidades. Cuando se usa junto con una selección de entidades, un atributo escalar devuelve una colección de valores escalares. Por ejemplo:

 locals:=ds.Person.query("city = :1";"San Jose") //selección de entidades de people
 localEmails:=locals.emailAddress //colección de direcciones de correo electrónico (cadenas)

Este código devuelve en localEmails una colección de direcciones de correo electrónico como cadenas.

Además de la variedad de formas en que puede realizar consultas, también puede usar atributos relación como propiedades de entity selections  para devolver nuevas entity selections. Por ejemplo, considere la siguiente estructura:

 myParts:=ds.Part.query("ID < 100") //Devuelve partes con ID inferior a 100
 $myInvoices:=myParts.invoiceItems.invoice
  //Todas las facturas con al menos una línea de pedido relacionada con una parte en myParts

La última línea devolverá enn $myInvoices una entity selection de todas las facturas que tengan al menos un ítem de factura relacionado con una parte en la entity selection myParts. Cuando un atributo relación se usa como una propiedad de una entity selection, el resultado es siempre otra entity selection, incluso si solo se devuelve una entidad. Cuando un atributo relación se usa como una propiedad de una entity selection y no se devuelven entidades, el resultado es una selección de entidad vacía, no null.

Una selección de entidades puede ser compartible (leíble por múltiples procesos, pero no alterable después de la creación) o modificable (soporta la función entitySelection.add( ), pero sólo utilizable por el proceso actual):

  • Una selección de entidades compartible tiene las siguientes características:
    • puede almacenarse en un objeto compartido o en una colección compartida, y puede pasarse como parámetro entre varios procesos o workers;
    • puede almacenarse en varios objetos o colecciones compartidas, o en un objeto o colección compartida que ya pertenece a un grupo (no tiene un identificador de bloqueo).
    • no permite la adición de nuevas entidades. Si se intenta añadir una entidad a una selección de entidades compartidas, se producirá un error (1637 - Esta selección de entidades no puede ser alterada). Para añadir una entidad a una selección de entidades compartida, primero debe transformarla en una selección de entidades no compartible utilizando la función entitySelection.copy( ), antes de llamar a entitySelection.add( ).
Nota: la mayoría de las funciones de selección de entidades (como entitySelection.slice( ), entitySelection.and( )...) soportan selecciones de entidades compartibles, ya que no necesitan alterar la selección de la entidad original (devuelven una nueva).

La naturaleza compartible o modificable de una selección de entidades se define cuando se crea la selección de entidad (no puede ser modificada posteriormente). Se puede conocer la naturaleza de la selección de una entidad utilizando la función entitySelection.isAlterable( ) o el comando OB Is shared.

Una nueva selección de entidades es compartible en los siguientes casos:

Ejemplo: 

 $myComp:=ds.Company.get(2) //$myComp no pertenece a una selección de entidades
 $employees:=$myComp.employees //$employees es compartible

Una selección de entidades es modificable en los siguientes casos:

Ejemplo:

 $toModify:=ds.Company.all().copy() //$toModify es modificable

Una nueva selección de entidades hereda la naturaleza de selección de entidades original en los siguientes casos:

  • la nueva selección de entidades resulta de una de las diversas funciones de clase ORDA aplicadas a una selección de entidades existente (entitySelection.query( ), entitySelection.slice( ), etc.) .
  • la nueva selección de entidades se basa en una relación:
    • entity.{attributeName} (por ejemplo, company.employees) cuando nomAtributo cuando el atributoName es un atributo relacionado de uno a muchos y la entidad pertenece a una selección de entidades (la misma naturaleza que la selección de entidades entity.getSelection( ))
    • entitySelection.{attributeName} (por ejemplo, employees.employer) cuando nomAtributo es un atributo relacionado de uno a varios (la misma naturaleza que la selección de entidades)
    • entitySelection.extract( ) cuando la colección resultante contiene selecciones de entidades (la misma naturaleza que la selección de entidades)

Ejemplos:

 $highSal:=ds.Employee.query("salary >= :1";1000000)&NBSP//$highSal es compartible por la búsqueda en dataClass
 $comp:=$highSal.employer //$comp es compartible porque $highSal es compartible
 
 $lowSal:=ds.Employee.query("salary <= :1";10000).copy()
  //$lowSal es modificable por copy()
 $comp2:=$lowSal.employer //$comp2 es modificable porque $lowSal es modificable

Nota de compatibilidad: es posible "forzar" que todas las nuevas selecciones de entidades sean modificables por defecto en su proyecto utilizando el método dataStore.makeSelectionsAlterable( ). Esta configuración de compatibilidad no se recomienda para proyectos nuevos.

Usted trabaja con dos selecciones de entidades que quiere pasar a un proceso worker para que pueda enviar correos a las personas adecuadas:

 var $paid;$unpaid : cs.InvoicesSelection
  //Obtener selecciones de entidades para las facturas pagadas y no pagadas
 $paid:=ds.Invoices.query("status=:1";"Paid")
 $unpaid:=ds.Invoices.query("status=:1";"Unpaid")
 
  //pasamos referencias de selecciones de entidades como parámetros al worker
 CALL WORKER("mailing";"sendMails";$paid;$unpaid)

El método sendMails:

 #DECLARE($paid cs.InvoicesSelection;$unpaid cs.InvoicesSelection)
 var $invoice : cs.InvoicesEntity
 
 var $server;$transporter;$email;$status : Object
 
  //Preparar emails
 $server:=New object
 $server.host:="exchange.company.com"
 $server.user:="myName@company.com"
 $server.password:="my!!password"
 $transporter:=SMTP New transporter($server)
 $email:=New object
 $email.from:="myName@company.com"
 
  //Bucles en selecciones de entidades
 For each($invoice;$paid)
    $email.to:=$invoice.customer.address // email del cliente
    $email.subject:="Payment OK for invoice # "+String($invoice.number)
    $status:=$transporter.send($email)
 End for each
 
 For each($invoice;$unpaid)
    $email.to:=$invoice.customer.address // email del cliente
    $email.subject:="Please pay invoice # "+String($invoice.number)
    $status:=$transporter.send($email)
 End for each

Las selecciones de entidades locales se pueden ordenar o no ordenar. Básicamente, ambos objetos tienen una funcionalidad similar, pero existen algunas diferencias con respecto a su rendimiento y funciones disponibles. Puede decidir qué tipo de entity selection utilizar según sus necesidades específicas.

Nota: las selecciones de entidades devueltas siempre se ordenan:

  • selecciones de entidades devueltas por 4D Server a un cliente remoto
  • selecciones de entidades construidas en datastores remotos.

  • Las selecciones de entidades no ordenadas se construyen sobre los bit tablas en la memoria. Una selección de entidades no ordenada contiene un bit para cada entidad de la dataclass, independientemente de si la entidad está realmente en la selección. Cada bit es igual a 1 o 0, para indicar si la entidad está o no incluida en la selección. Es una representación muy compacta para cada entidad.
    Por consiguiente, las operaciones que utilizan selecciones de entidades no ordenadas son muy rápidas. Además, las selecciones de entidades no ordenadas son muy económicas en términos de espacio de memoria. El tamaño de una selección de entidades no ordenada, en bytes, siempre es igual al número total de entidades en la dataclass dividido entre 8. Por ejemplo, si crea una selección de entidades no ordenada para una dataclass  que contiene 10.000 entidades, ocupará 1.250 bytes, que es aproximadamente 1.2K en RAM.
    Por otro lado, las selecciones de entidades no ordenadas no pueden ordenarse. No puede confiar en la posición de las entidades dentro de la selección. Además, no puede tener más de una referencia a la misma entidad en la selección: cada entidad solo se puede agregar una vez.
  • Las selección de entidades ordenadas se crean sobre arrays enteros largos (que contienen referencias de entidad) en la memoria. Cada referencia a una entidad toma 4 bytes en la memoria. Procesar y mantener dichas selecciones lleva más tiempo y requiere más espacio de memoria que las selecciones sin ordenar.
    Por otro lado, se pueden ordenar o reordenar, y puede confiar en las posiciones de la entidad. Además, puede agregar más de una referencia a la misma entidad.

La siguiente tabla resume las principales funcionalidades de cada tipo de selección de entidades:

FuncionalidadSelección de entidades no ordenadaSelección de entidades ordenada
Velocidad de procesamientomuy rápidomás lento
Tamaño en la memoriamuy pequeñomás grande
Puede contener varias referencias a una entidadno

Por razones de optimización, por defecto, ORDA generalmente crea las selecciones de entidades no ordenadas, excepto cuando utiliza el método orderBy( ) o si utiliza las opciones apropiadas (ver a continuación). En esta documentación, a menos que se especifique "selección de entidades" generalmente se refiere a una "selección de entidades no ordenada".

Como se mencionó anteriormente, ORDA por defecto crea y maneja entity selections no ordenadas como resultado de operaciones tales como consultas o comparaciones como and( ). Las entity selections ordenadas se crean solo cuando es necesario o cuando se solicitan específicamente mediante el uso de opciones.

Las entity selections ordenadas se crean en los siguientes casos:

  • resultado de un orderBy( ) en una selección (de cualquier tipo) o una orderBy( ) en una dataclass
  • resultado del método newSelection( ) con la opción dk keep ordered

Las entity selections desordenadas se crean en los siguientes casos:

  • resultado de una query( ) estándar en una selección (de cualquier tipo) o una query( ) en una dataclass,
  • resultado del método newSelection( ) sin opción,
  • resultado de cualquiera de los métodos de comparación, cualquiera que sea el tipo de selección de entrada: or( ), and( ), minus( ).

Tenga en cuenta que cuando una entity selection ordenada se convierte en una entity selection desordenada, cualquier referencia de entidad repetida se elimina.

Si desea transformar una entity selection ordenada en una no ordenada, puede simplemente aplicarle una operación and( ), por ejemplo:

  //mySel es una entity selection ordenada
 mySel:=mySel.and(mySel)
  //mySel ahora es una entity selection desordenada

4D ofrece una optimización automática para las peticiones ORDA que utilizan selecciones de entidades o cargan entidades en las configuraciones cliente/servidor. Esta optimización acelera la ejecución de su aplicación 4D al reducir drásticamente el volumen de información transmitida a través de la red.


Se implementan los siguientes mecanismos de optimización:

  • Cuando un cliente solicita una selección de entidades del servidor, 4D "aprende" automáticamente qué atributos de la selección de entidades se utilizan realmente del lado del cliente durante la ejecución del código, y crea un "contexto de optimización" correspondiente. Este contexto se adjunta a la selección de entidades y almacena los atributos utilizados. Se actualizará dinámicamente si luego se utilizan otros atributos.
  • Las solicitudes posteriores enviadas al servidor en la misma selección de entidades reutilizan automáticamente el contexto de optimización y solo obtienen los atributos necesarios del servidor, lo que acelera el procesamiento. Por ejemplo, en un list box basado en la selección de entidades, la fase de aprendizaje tiene lugar durante la visualización de las primeras filas, la visualización de las siguientes filas está muy optimizada.
  • Un contexto de optimización existente se puede pasar como una propiedad a otra selección de entidades de la misma clase de datos, por lo que se pasa por alto la fase de aprendizaje y se acelera la aplicación (ver abajo "Uso de la propiedad de contexto").

Los siguientes métodos asocian automáticamente el contexto de optimización de la selección de entidades de origen a la selección de entidades devuelta:

Ejemplo

Dado el siguiente código:

 $sel:=$ds.Employee.query("firstname = ab@")
 For each($e;$sel)
    $s:=$e.firstname+" "+$e.lastname+" works for "+$e.employer.name // $e.employer se refiere a la tabla Company
 End for each

Gracias a la optimización, esta solicitud solo obtendrá datos de los atributos utilizados (nombre, apellido, empleador, empleador.nombre) en $sel después de una fase de aprendizaje.

Utilizando la propiedad de contexto

Puede aumentar los beneficios de la optimización utilizando la propiedad contexto. Esta propiedad hace referencia a un contexto de optimización "aprendido" para una selección de entidades. Se puede pasar como parámetro a los métodos ORDA que devuelven nuevas selecciones de entidades, de modo que las selecciones de entidades soliciten directamente los atributos utilizados al servidor y omitan la fase de aprendizaje.

Una misma propiedad de contexto de optimización se puede pasar a un número ilimitado de selecciones de entidades en la misma clase de datos. Todos los métodos ORDA que manejan las selecciones de entidades admiten la propiedad contexto (por ejemplo, el método dataClass.query( ) o dataClass.all( )). Sin embargo, tenga en cuenta que un contexto se actualiza automáticamente cuando se usan nuevos atributos en otras partes del código. Reutilizar el mismo contexto en diferentes códigos podría resultar en una sobrecarga del contexto y luego reducir su eficiencia.

Nota: se implementa un mecanismo similar para las entidades que se cargan, de modo que solo se solicitan los atributos utilizados (ver el método dataClass.get( )). 

Ejemplo con el método dataClass.query( )

 C_OBJECT($sel1;$sel2;$sel3;$sel4;$querysettings;$querysettings2)
 C_COLLECTION($data)
 $querysettings:=New object("context";"shortList")
 $querysettings2:=New object("context";"longList")
 
 $sel1:=ds.Employee.query("lastname = S@";$querysettings)
 $data:=extractData($sel1// En el método extractData, una optimización se activa y se asocia al contexto "shortList"
 
 $sel2:=ds.Employee.query("lastname = Sm@";$querysettings)
 $data:=extractData($sel2// En el método extractData, se aplica la optimización asociada al contexto "shortList"
 
 $sel3:=ds.Employee.query("lastname = Smith";$querysettings2)
 $data:=extractDetailedData($sel3// En el método extractDetailedData se desencadena una optimización y se asocia al contexto "longList"
 
 $sel4:=ds.Employee.query("lastname = Brown";$querysettings2)</p><p>$data:=extractDetailedData($sel4//En el método extractDetailedData, se aplica la optimización asociada al contexto "longList"

List box basado en la selección de entidades

La optimización de la selección de entidades se aplica automáticamente a los list boxes basados ​​en selección de entidades en las configuraciones cliente/servidor, al mostrar y desplazar el contenido de un list box: solo los atributos mostrados en el list box se solicitan desde el servidor.
También se ofrece un contexto específico de "modo de página" al cargar la entidad actual a través de la expresión de propiedad del elemento actual del list box (consulte List boxes de tipo Colección o entity selection). Esta funcionalidad le permite no sobrecargar el contexto inicial del list box en este caso, especialmente si la "página" solicita atributos adicionales. Tenga en cuenta que solo el uso de la expresión del elemento actual creará/utilizará el contexto de la página (el acceso a través de entitySelection[index] alterará el contexto de selección de la entidad).

Las peticiones subsiguientes al servidor enviadas por los métodos de navegación de entidades también apoyarán esta optimización. Los siguientes métodos asocian automáticamente el contexto de optimización de la entidad de origen a la entidad devuelta:

Por ejemplo, el siguiente código carga la entidad seleccionada y permite navegar en la selección de entidades. Las entidades se cargan en un contexto separado y el contexto inicial del list box se deja sin tocar:

 $myEntity:=Form.currentElement //expresión del elemento actual
  //... hacer algo
 $myEntity:=$myEntity.next() //carga la entidad siguiente utilizando el mismo contexto

Nota de compatibilidad: los contextos manejados en conexiones determinadas a través de Open datastore sólo pueden ser utilizados entre versiones principales similares de 4D. Por ejemplo, una aplicación remota 4D v19.x sólo puede utilizar contextos de un datastore 4D Server v19.x.

El objeto selección de entidades en sí mismo no se puede copiar como un objeto:

 $myentitysel:=OB Copy(ds.Employee.all()) //returns null

Sin embargo, las propiedades selección de entidades son enumerables:

 ARRAY TEXT($prop;0)
 OB GET PROPERTY NAMES(ds.Employee.all();$prop)
  //$prop contiene los nombres de las propiedades de entity selection
  //("length", 00", "01"...)

 
PROPIEDADES 

Producto: 4D
Tema: ORDA

 
CONTENIDO DE LA PÁGINA 
 
HISTORIA 

Creado por: 4D v17
Modificado: 4D v18 R5

 
ARTICLE USAGE

Manual de Diseño ( 4D v19)