4D v18

Sélections d'entités

Accueil

 
4D v18
Sélections d'entités

Sélections d'entités  


 

Aperçu  

Une sélection d'entités est un objet contenant une ou plusieurs référence(s) à des entités appartenant à la même dataclass. Une sélection d'entités peut contenir 0, 1 ou X entités de la dataclass - où X peut représenter le nombre total d'entités contenues dans la dataclass. Les sélections d'entités peuvent être "triées" ou "non-triées" (ce point est discuté ci-dessous). 

Les sélections d'entités sont généralement créées à l'aide d'une requête ou renvoyés à partir d'un attribut relationnel. Par exemple :

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

Ce code renvoie dans brokers toutes les personnes de type courtier. Pour accéder à une entité de la sélection, utilisez une syntaxe similaire à l'accès à un élément dans une collection. Par exemple :

 theBroker:=brokers[0]  //Les sélections d'entités sont basées sur 0

La méthode entitySelection.orderBy( ) retourne une nouvelle sélection d'entités en fonction de critères de tri fournis. Par exemple :

 brokers:=brokers.orderBy("name") //renvoie une sélection triée

Ce code renvoie dans brokers la même sélection d'entités de Person, mais triée par nom.

Vous pouvez également utiliser un attribut relationnel pour renvoyer une sélection d'entités. Par exemple :

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

Ce code assigne à brokerCompanies toutes les sociétés liées à des personnes de la sélection d'entités brokers, en utilisant l'attribut relationnel myCompany. L'utilisation des attributs relationnels sur les sélections d'entités est un moyen puissant et facile de naviguer dans la chaîne des entités associées.

Pour effectuer des actions répétées sur des entités dans une sélection d'entités, comme récupérer et modifier des valeurs de certains attributs, vous pouvez utiliser la structure Pour chaque...Fin de chaque. Par exemple :

 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

Vous pouvez créer un objet de type sélection d'entités comme suit :

Vous pouvez simultanément créer et utiliser autant de sélection d'entités que vous le souhaitez pour une dataclass.

Gardez à l'esprit qu'une sélection d'entités contient uniquement des références à des entités. Des sélections d'entités différentes peuvent contenir des références aux mêmes entités.

Note : Une sélection d'entités est définie uniquement dans le process où elle a été créée. Vous ne pouvez pas, par exemple, stocker la référence d'une sélection d'entités dans une variable interprocess et l'utiliser dans un autre process.  

Tous les attributs de stockage (texte, nombre, booléen, date) sont disponibles en tant que propriétés des sélections d'entités et des entités. Lorsqu'il est utilisé conjointement avec une sélection d'entité, un attribut scalaire renvoie une collection de valeurs scalaires. Par exemple :

 locals:=ds.Person.query("city = :1";"San Jose") //Sélection des entités Person
 localEmails:=locals.emailAddress //collection des adresses e-mail (chaînes)

Ce code renvoie dans localEmails une collection d'adresses e-mail sous forme de chaînes.

En plus de la variété de méthodes que vous pouvez utiliser, vous pouvez également utiliser les attributs relationnels comme propriétés des sélections d'entités pour renvoyer de nouvelles sélection d'entités. Par exemple, considérez la structure suivante :

 myParts:=ds.Part.query("ID < 100") //Retourne Parts avec un ID inférieur à 100
 $myInvoices:=myParts.invoiceItems.invoice
  //Toutes les factures ("Invoice") avec au moins une ligne ("InvoiceItem") reliée à un produit ("Part") dans myParts

La dernière ligne retournera dans $myInvoices une sélection d'entités de toutes les factures qui ont au moins un élément de factures lié à une partie de sélection d'entités dans myParts. Lorsqu'un attribut relationnel est utilisé en tant que propriété d'une sélection d'entités, le résultat est toujours une autre sélection d'entités, même si une seule entité est renvoyée. Lorsqu'un attribut relationnel est utilisé en tant que propriété d'une sélection d'entités et qu'aucune entité n'est renvoyée, le résultat est une sélection d'entités vide, et non null

Les sélections d'entités locales peuvent être triées ou non-triées. Fondamentalement, les deux objets ont des fonctionnalités similaires, mais il existe des différences en termes de performances et de fonctionnalités disponibles. Vous pouvez décider du type de sélection d'entités à utiliser en fonction de vos besoins spécifiques.

Note : Les sélections d'entités suivantes sont toujours triées: 

  • sélections d'entités retournées par 4D Server vers un client distant
  • sélections d'entités fondées sur des datastores distants.
 
 

  • Les sélections d'entités non-ordonnées sont construites sur des bit tables en mémoire. Une sélection d'entités non-triées contient un bit pour chaque entité de la dataclass, indépendamment du fait que l'entité soit réellement ou pas dans la sélection. Chaque bit est égal à 1 ou 0, pour indiquer si l'entité est incluse ou non dans la sélection. C'est une représentation très compacte pour chaque entité.
    Par conséquent, les opérations utilisant des sélections d'entités non ordonnées sont très rapides. De plus, les sélections d'entités non ordonnées sont très économiques en terme d'espace mémoire. La taille d'une sélection d'entités non ordonnées, en octets, est toujours égale au nombre total d'entités de la dataclass divisé par 8. Par exemple, si vous créez une sélection d'entités non ordonnées pour une dataclass contenant 10 000 entités, elle occupera 1 250 octets, ce qui représente environ 1,2 Ko en RAM.
    D'un autre côté, les sélections d'entités non ordonnées ne peuvent pas être triées. Vous ne pouvez pas compter sur la position des entités dans la sélection. En outre, vous ne pouvez pas avoir plus d'une référence à la même entité dans la sélection : chaque entité ne peut être ajoutée qu'une seule fois.
  • Les sélections d'entités ordonnées sont construites sur des tableaux Entier long (contenant des références d'entités) en mémoire. Chaque référence à une entité prend 4 octets en mémoire. Le traitement et la maintenance de ces sélections prennent plus de temps et nécessitent plus d'espace mémoire que les sélections non-triées.
    D'un autre côté, elles peuvent être triées ou réorganisées, et vous pouvez compter sur des positions d'entités. En outre, vous pouvez ajouter plusieurs références à la même entité.

Le tableau suivant résume les principales caractéristiques de chaque type de sélection d'entités :

FonctionnalitéSélection d'entités non-triéeSélection d'entités triée
Vitesse de traitementtrès rapideplus lent
Taille en mémoiretrès petiteplus grande
Peut contenir plusieurs références à une entiténonoui

Pour des raisons d'optimisation, par défaut, 4D ORDA crée généralement des sélections d'entités non-ordonnées, sauf lorsque vous utilisez la méthode orderBy( ) ou si vous utilisez les options appropriées (voir ci-dessous). Dans cette documentation, sauf indication contraire, "sélection d'entités" fait généralement réféernce à une "sélection d'entités non-ordonnée".

 
 

Comme mentionné ci-dessus, par défaut, ORDA crée et gère les sélections d'entités non-ordonnées à la suite d'opérations telles que des requêtes ou des comparaisons comme and( ). Les sélections d'entités ordonnées sont créées uniquement lorsque cela est nécessaire ou lorsqu'elles sont spécifiquement demandées à l'aide d'options.

Les sélections d'entités triées sont créées dans les cas suivants :

  • résultat d'un orderBy( ) sur une sélection (de n'importe quel type) ou un orderBy( ) sur une dataclass,
  • résultat de la méthode newSelection( ) avec l'option dk keep ordered.

Les sélections d'entités non-triées sont créées dans les cas suivants :

  • résultat d'un query( ) standard sur une sélection (de n'importe quel type) ou un query( ) sur une dataclass,
  • résultat de la méthode newSelection( ) sans option,
  • résultat de l'une des méthodes de comparaison, quel que soit le type de sélection saisi : or( ), and( ), minus( ).

Notez que lorsqu'une sélection d'entités ordonnée devient une sélection non-ordonnée, toute référence d'entité répétée est supprimée.

Si vous voulez transformer une sélection d'entités ordonnée en une sélection non-ordonnée, vous pouvez simplement lui appliquer une opération and( ), par exemple :

  //mySel est une sélection d'entités ordonnée
 mySel:=mySel.and(mySel)
  //mySel est maintenant une sélection d'entités non-ordonnée

4D optimise automatiquement les requêtes ORDA qui utilisent des sélections d'entités ou qui chargent des entités en configuration client/serveur. Cette optimisation accélère l'exécution de votre application 4D en réduisant considérablement le volume d'informations transmises sur le réseau.

Les mécanismes d'optimisation suivants sont mis en oeuvre :

  • Lorsqu'un client demande une sélection d'entités au serveur, 4D "apprend" automatiquement les attributs de la sélection d'entités qui sont utilisés côté client lors de l'exécution du code et génère un "contexte d'optimisation". Ce contexte est relié à la sélection d'entités et stocke les attributs utilisés. Il sera mis à jour dynamiquement si d'autres attributs sont utilisés ultérieurement.
  • Les requêtes ultérieures qui sont envoyées au serveur à la même sélection d'entités réutilisent automatiquement le contexte d'optimisation et lisent uniquement les attributs nécessaires depuis le serveur, ce qui accélère le traitement. Par exemple, dans une listbox basée sur une sélection d'entités, la phase d'apprentissage a lieu durant l'affichage des premières lignes et l'affichage des lignes suivantes est fortement optimisé.
  • Un contexte d'optimisation existant peut être passé comme propriété à une autre sélection d'entités de la même dataclass, ce qui perment d'éviter la phase d'apprentissage et d'accélérer l'application (voir "Utilisation de la propriété context" ci-dessous).

Les méthodes suivantes associent automatiquement le contexte d'optimisation de la sélection d'entités d'origine à la sélection d'entités retournée :

Exemple

Considérons le code suivant :

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

Grâce à l'optimisation, cette requête récupérera uniquement les données issues des attributs utilisés (firstname, lastname, employer, employer.name) dans $sel après la phase d'apprentissage. 

 

Utilisation de la propriété context

Vous pouvez tirer un meilleur parti de l'optimisation en utilisant la propriété context. Cette propriété référence un contexte d'optimisation "appris" pour une sélection d'entités. Elle peut être passée comme paramètre aux méthodes ORDA qui retournent de nouvelles sélections d'entités, afin que les sélections d'entités demandent directement au serveur les attributs utilisés, sans passer par la phase d'apprentissage.

Une même propriété de contexte d'optimisation peut être passée à un nombre illimité de sélections d'entités de la même dataclass. Toutes les méthodes ORDA qui gèrent les sélections d'entités prennent en charge la propriété context (par exemple les méthodes dataClass.query( ) ou dataClass.all( )). Il est toutefois important de garder à l'esprit qu'un contexte est automatiquement mis à jour lorsque de nouveaux attributs sont utilisés dans d'autres parties du code. Si le même contexte est réutilisé dans différents codes, il risque d'être surchargé et de perdre en efficacité.

Note : Un mécanisme similaire est mis en place pour des entités qui sont chargées, afin que seuls les attributs utilisés soient demandés (voir la méthode dataClass.get( )). 

Exemple avec la méthode 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// Dans la méthode extractData, une optimisation est déclenchée et associée au contexte "shortList"
 
 $sel2:=ds.Employee.query("lastname = Sm@";$querysettings)
 $data:=extractData($sel2// Dans la méthode extractData, l'optimisation associée au contexte "shortList" est appliquée
 
 $sel3:=ds.Employee.query("lastname = Smith";$querysettings2)
 $data:=extractDetailedData($sel3// Dans la méthode extractDetailedData, une optimisation est déclenchée et associée au contexte "longList"
 
 $sel4:=ds.Employee.query("lastname = Brown";$querysettings2)
 $data:=extractDetailedData($sel4// Dans la méthode extractDetailedData, l'optimisation associée au contexte "longList" est appliquée

Listbox basée sur une sélection d'entités

L'optimisation d'une sélection d'entités s'applique automatiquement aux listbox basées sur une sélection d'entités dans les configurations client/serveur, au moment d'afficher et de dérouler le contenu d'une listbox : seuls les attributs affichés dans la listbox sont demandés depuis le serveur.
Un contexte spécifique nommé "mode page" est également proposé lorsque l'entité courante de la sélection est chargée à l'aide de l'expression Élément courant de la listbox (voir List box type collection ou entity selection). Cette fonctionnalité vous permet de ne pas surcharger le contexte initial de la listbox dans ce cas précis, notamment si la "page" requiert des attributs supplémentaires. A noter que seule l'utilisation de l'expression Élément courant permettra de créer/utiliser le contexte de la page (l'accès via entitySelection[index] modifiera le contexte de la sélection d'entité).
Cette optimisation sera également prise en charge par les requêtes ultérieures envoyées au serveur via les méthodes de navigation des entités. Les méthodes suivantes associeront automatiquement le contexte d'optimisation de l'entité source à l'entité retournée :

Par exemple, le code ci-dessous charge l'entité sélectionnée et permet de naviguer dans la sélection d'entités. Les entités sont chargées dans un contexte séparé et le contexte initial de la listbox demeure inchangé :

 $myEntity:=Form.currentElement // expression de l'élément courant
  //... faire quelque chose
 $myEntity:=$myEntity.next() //charge la prochaine entité à l'aide du même contexte

 

L'objet sélection d'entités lui-même ne peut pas être copié en tant qu'objet :

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

Les propriétés des sélections d'entités sont toutefois énumérables :

 ARRAY TEXT($prop;0)
 OB GET PROPERTY NAMES(ds.Employee.all();$prop)
  //$prop contient les noms des propriétés des sélections d'entités
  //("length", "00", "01"...)

 
PROPRIÉTÉS 

Produit : 4D
Thème : ORDA

 
PAGE CONTENTS 
 
HISTORIQUE 

Créé : 4D v17

 
UTILISATION DE L'ARTICLE

4D - Mode Développement ( 4D v18)