Este é o site histórico da documentação 4D. As documentações estão sendo movidas progressivamente para developer.4d.com

Página Inicial

 
4D v19
Entity selections

Entity selections  


 

Uma entity selection é um objeto que contém uma ou mais referências a entidades que pertecem à mesma dataclass. Uma entity selection pode conter 0, 1 ou entidades X da dataclass, onde X pode representar a quantidade total de entidades contidas na dataclass.

As seleções de entidade podem ser :

  • "ordenadas" ou "não ordenadas"
  • "compartilhável" ou "não compartilhável"
Esses pontos serão analisados abaixo

As entity selections geralmente são criadas utilizando uma pesquisa ou são retornadas desde um atributo relação. Por exemplo:

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

Este código retorna em brokers todas as pessoas de tipo broker. Para acessar a uma entidade da seleção, utilize uma sintaxe similar para acessar a um elemento em uma coleção. Por exemplo:

 theBroker:=brokers[0]  //As entity selections estão baseadas em 0


O método entitySelection.orderBy( ) retorna uma nova seleção de entidade de acordo com os critérios de classificação fornecidos. Por exemplo:

 brokers:=brokers.orderBy("name") //retorna uma seleção ordenada

Este código retorna em brokers a mesma seleção de entidade das entidades Person, mas ordenadas por nome.

Alternativamente, pode usar um atributo relação para devolver uma seleção de entidade. Por exemplo:

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

Este código atribui a brokerCompanies todas as empresas relacionadas das pessoas na seleção de entidade brokers, utilizando o atributo de relação myCompany. O uso de atributos de relação nas seleções de entidades é uma forma poderosa e fácil de navegar para cima e para baixo a série de entidades relacionadas.

Para realizar ações repetidas a entidades em uma seleção de entidades, como recuperar e modificar valores de certos atributos, pode usar a estrutura For each...End for each. Por exemplo:

 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

É possível criar  um  objeto de tipo entity selection da seguinte maneira:

Pode criar e usar simultaneamente tantas entity selections diferentes quantas queira para uma dataclass. Lembre que uma entity selection só contém referências a entidades. As diferentes entity selections podem conter referências às mesmas entidades.

Nota: Uma seleção de entidade pode ser usada em processos diferentes apenas se for partilhável. Para saber mais veja o parágrafo Seleção de Entidade Compatível vs Não-compatível.

Todos os atributos de armazenamento (texto, número, booleano, data) estão disponíveis como propriedades das entity selections assim como das entidades. Quando for usado junto com uma entity selection, um atributo escalar retorna uma coleção de valores escalares. Por exemplo:

 locals:=ds.Person.query("city = :1";"San Jose") //entity selection de people
 localEmails:=locals.emailAddress //coleção de endereços de correio eletrônico (strings)

Este código retorna em localEmails uma coleção de endereços de correio eletrônico como strings.

Além da variedade de formas em que pode realizar consultas, também pode usar atributos relação como propriedades de entity selections  para devolver novas entity selections. Por exemplo, considere a estrutura abaixo:

 myParts:=ds.Part.query("ID < 100") //Retorna partes com ID inferior a 100
 $myInvoices:=myParts.invoiceItems.invoice
  //Todas as faturas com pelo menos uma linha de pedido relacionada com uma parte em myParts

A última linha devolverá em $myInvoices uma entity selection de todas as faturas que tenham pelo menos um item de fatura  relacionado com uma parte na entity selection myParts. Quando um atributo relação for usado como uma propriedade de una entity selection, o resultado é sempre outra entity selection, mesmo se apenas for  devolvida uma entidade. Quando um atributo relação for usado como uma propriedade de uma entity selection e não forem retornadas entidades, o resultado é uma seleção de entidade vazia, não null.

Uma seleção de entidades pode ser compartilhável (não modificável) ou não compartilhável (modificável).

  • Uma seleção compartilhável de entidades tem as seguintes características:
    •   pode ser armazenado em um objeto compartilhado ou em uma coleção compartilhada, e pode ser compartilhado entre vários processos ou trabalhadores 
    •   pode ser armazenado em vários objetos ou coleções compartilhadas, ou em um objeto ou coleção compartilhada que já pertença a um grupo (não tem um ID de bloqueio).
    • não permite a adição de novas entidades. A tentativa de adicionar uma entidade a uma seleção de entidades compartilhadas resultará em um erro (1637 - Esta seleção de entidades não pode ser alterada). Para adicionar uma entidade a uma seleção de entidades compartilhadas, você deve primeiro transformá-la em uma seleção de entidades não compartilhadas usando a função entitySelection.copy( ), antes de chamar entitySelection.add( )..

Nota: A maioria das funções de seleção de entidades (such as entitySelection.slice( ), entitySelection.and( )...) são compatíveis com seleções de entida compartilháveis já que não precisam alterar a seleção de entidade original  (retornam uma nova).

  • Uma seleção não compartilhável de entidades tem as seguintes características::
    • não pode ser compartilhado entre processos, nem armazenado em um objeto ou coleção compartilhada. A tentativa de armazenar uma seleção de entidade não compartilhada em um objeto ou coleção compartilhada resultará em um erro (-10721 - Tipo de valor não suportado em um objeto ou coleção compartilhada)
    • aceita a adição de novas entidades, ou seja é compatível com a função entitySelection.add( ).
A natureza compartilhável ou alterável da seleção de entidade é definida quando a seleção de entidade for criada (não pode ser modificada depois). Pode achar a natureza de uma seleção de entidade usando a função entitySelection.isAlterable( ) ou o comando OB Is shared.

Uma nova seleção de entidade é compartilhável nos casos abaixo:

Na maioria dos casos, as novas seleções de entidades são compartilháveis, incluindo

  •  a nova seleção de entidades resultantes de funções de classe ORDA aplicadas à dataclass (entitySelection.query( ), dataClass.query( ), etc.),
  •  a nova seleção de entidades é baseada na relação entity.{attributeName} (por exemplo, empresa.funcionário) quando o atributoNome for um atributo de relação um-para-muitos e a entidade não pertence a uma seleção de entidades
  • seleções de entidades copiadas explicitamente como sendo compartilhadas com entitySelection.copy( ) ou OB Copy (ou seja a opção ck shared).
Exemplo:

 $myComp:=ds.Company.get(2) //$myComp não pertence a uma seleção de entidades
 $employees:=$myComp.employees //$employees é compartilhavel


Uma nova seleção de entidades é alterável nos casos abaixo:

seleções de entidade em branco criadas usando a função dataClass.newSelection( ) ou o comando Criar seleção de entidade
a nova seleção de entidade é copiada explicitamente como alterável com entitySelection.copy( ) ou OB Copy (ou seja sem a opção ck shared).

Exemplo:

 $toModify:=ds.Company.all().copy() //$toModify é alterável


Uma nova seleção de entidades herda da natureza da seleção de entidade original nos casos abaixo:

a nova seleção de entidade resulta de uma das várias funções de classe ORDA aplicadas a uma seleção de entidade existente (entitySelection.query( ), entitySelection.slice( ), etc.) . A nova seleção de entidade é basea numa relação:
        entity.{attributeName} (por exemplo empresa/funcionários) quando atributoNome for um atributo de relação um para muitos e a entidade pertencer a uma seleção de entidades (mesma natureza que uma seleção de entidade entity.getSelection( ))
        entitySelection.{attributeName} (por exemplo. funcionarios/empregador) quando attributeName for um atributo de relação um para muitos (mesma natureza que a seleção de entidade)

        entitySelection.extract( ) quando a coleção resultante conter seleções de entidade (mesma natureza que uma seleção de entidade)
 
Exemplos:


 $highSal:=ds.Employee.query("salary >= :1";1000000)&NBSP//$highSal é compartilhável por causa da pesquisa em dataClass
 $comp:=$highSal.employer //$comp é partilhável porque  $highSal é partilhável
 
 $lowSal:=ds.Employee.query("salary <= :1";10000).copy()
  //$lowSal is alterable because of the copy()
 $comp2:=$lowSal.employer //$comp2 é alterável porque $lowSal é alterável


Nota de compatibilidade: é possível "forçar" todas as novas seleções de entidade a serem alteráveis como padrão em seu projeto usando o método dataStore.makeSelectionsAlterable( ). Essa configuração de entidade não é recomendada para novos projetos.

Se trabalhar com duas seleções de entidades que queira passar a um processo worker para que possa enviar correios às pessoas adequadas:

 var $paid;$unpaid : cs.InvoicesSelection
  //criar seleções de entidades para faturas pagadas ou a pagar
 $paid:=ds.Invoices.query("status=:1";"Paid")
 $unpaid:=ds.Invoices.query("status=:1";"Unpaid")
 
  //Passamos referências de seleção de entidade como parâmetros ao trabalhador
 CALL WORKER("mailing";"sendMails";$paid;$unpaid)
]

O 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"
 
  //Loops nas seleções de entidade
 For each($invoice;$paid)
    $email.to:=$invoice.customer.address // endereço de email do 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 // endereço de email do cliente
    $email.subject:="Please pay invoice # "+String($invoice.number)
    $status:=$transporter.send($email)
 End for each

As entity selections locais  podem ser ordenadas ou não ordenadas. Basicamente, ambos objetos têm uma funcionalidade similar, mas existem algumas diferenças com respeito a seu rendimento e funções disponíveis. Pode decidir que tipo de entity selection usar segundo suas necessidades específicas.

Nota: as Entity selections em uma devolvidas por 4D Server a um cliente remoto sempre são ordenadas.

  • As entity selections desordenadas são construídas sobre tabelas de bits na memória. Uma entity selection desordenada contém um bit para cada entidade na dataclass, independentemente de se a entidade estiver realmente na seleção. Cada bit é igual a 1 ou 0, para indicar se a entidade estiver ou não  incluída na seleção. É uma representação muito compacta para cada entidade.
    Como consequência, as operações que utilizam entity selections não ordenadas são muito rápidas. Além disso, as entity selections desordenadas são econômicas em termos de espaço de memória. O tamanho de uma entity selection desordenada, em bytes, sempre é igual ao número total de entidades na dataclass dividido entre 8. Por exemplo, se criar uma  entity selection desordenada para uma dataclass  que contenha 10.000 entidades, ocupará 1.250 bytes, que é aproximadamente 1.2K em RAM.
    Por outro lado, as entity selections não ordenadas não podem ser ordenadas. Não pode confiar na posição das entidades dentro da seleção. Além disso, não pode ter mais de uma referência à mesma entidade na seleção: cada entidade só pode ser agregado uma vez.

 

  • As entity selections ordenadas são criadas sobre arrays inteiros longos (que contenham referências de entidade) na memória. Cada referência a uma entidade toma 4 bytes na memória. Processar e manter essas seleções leva mais tiempo e exige mais espaço de memória que as seleções sem ordenar.
    Por outro lado, podem ser ordenadas ou reordenar, e pode confiar nas posições da entidade. Além disso, pode agregar mais de uma referência à mesma entidade.

A tabela abaixo resume as principais funcionalidades de cada tipo de entity selection:

FuncionalidadeEntity selection desordenadaEntity selection ordenada
Velocidade de processamentomuito rápidomais lento
Tamanho na memóriamuito pequenomaior
Pode conter várias referências a uma entidadenãosim

Por razões de otimização, como padrão normal, 4D ORDA geralmente cria entity selections não ordenadas, exceto quando utilizar o método orderBy( ) ou usar as opções apropriadas (ver a continuação). Nesta documentação, a menos que se especifique "entity selection" geralmente se refere a uma "entity selection desordenada".

Como se mencionou anteriormente, ORDA por padrão cria e maneja entity selections não ordenadas como resultado de operações tais como consultas ou comparações como and( ). As entity selections ordenadas são criadas só quando for necessário ou quando são solicitadas especificamente mediante o uso de opções.

As entity selections ordenadas são criadas nos casos abaixo:

  • resultado de um orderBy( ) em uma seleção (de qualquer tipo) ou uma orderBy( ) em uma dataclass
  • resultado do método newSelection( ) com a opção dk keep ordered

As entity selections desordenadas são criadas nos casos abaixo:

  • resultado de uma query( ) padrão em uma seleção (de qualquer tipo) ou uma query( ) em uma dataclass,
  • resultado do método newSelection( ) sem opção,
  • resultado de qualquer um dos métodos de comparação, qualquer que seja o tipo de seleção de entrada: or( ), and( ), minus( ).

Lembre que quando uma entity selection ordenada são convertida em uma entity selection desordenada, qualquer referência de entidade repetida é eliminada.

Se quiser transformar uma entity selection ordenada em uma não ordenada, pode simplesmente aplicar uma operação and( ), por exemplo:

  //mySel é uma entity selection ordenada
 mySel:=mySel.and(mySel)
  //mySel agora é uma entity selection desordenada

4D oferece uma otimização automática para as petições ORDA que utilizam seleções de entidades ou carregam entidades nas configurações cliente/servidor. Esta otimização acelera a execução de sua aplicação 4D ao reduzir drasticamente o volume de informação transmitida através da rede.


São implementadas os seguintes mecanismos de otimização:

  • Quando um cliente solicita uma seleção de entidades de servidor, 4D "aprende" automaticamente que atributos da seleção de entidades são utilizadas realmente do lado do cliente durante a execução de código, e cria um "contexto de otimização" correspondente. Este contexto se anexa à seleção de entidades e armazena os atributos utilizados. Se atualizará dinamicamente se depois forem utilizados outros atributos.
  • As petições posteriores enviadas ao servidor na mesma seleção de entidades reutilizam automaticamente o contexto de otimização e apenas obtém os atributos necessários do servidor, o que acelera o processamento. Por exemplo, em um list box baseado na seleção de entidades, a fase de aprendizagem é feita durante a visualização das primeiras filas, a visualização das filas seguintes está muito otimizada.
  • Um contexto de otimização existente pode ser passada como uma propriedade a outra seleção de entidades da mesma classe de dados, pelo que se ignora a fase de aprendizagem e se acelera a aplicação (ver abaixo "Uso da propriedade de contexto").

Os métodos abaixo associam automaticamente o contexto de otimização da seleção de entidades de origem à seleção de entidades devolvidas:

Exemplo

Dado o código abaixo:

 $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

Graças à otimização, esta solicitude apenas obterá dados dos atributos utilizados (nome, sobrenome, empregador, empregador.nome) em $sel depois de uma fase de aprendizagem.

Utilizando a propriedade de contexto

Pode aumentar os beneficios da otimização utilizando a propriedade contexto. Esta propriedade faz referência a um contexto de otimização "aprendido" para uma seleção de entidades. Se pode passar como parâmetro aos métodos ORDA que devolvem novas seleções de entidades, de modo que as seleções de entidades solicitem diretamente aos atributos utilizados ao servidor e omitem a fase de aprendizagem.

Uma mesma propriedade de contexto de otimização pode ser passada a um número ilimitado de seleções de entidades na mesma classe de dados. Todos os métodos ORDA que manejam as seleções de entidades admitem a propriedad contexto (por exemplo, o método dataClass.query( ) ou dataClass.all( )). Entretanto, lembre que um contexto se atualiza automaticamente quando forem usados novos atributos em outras partes do código. Reutilizar o mesmo contexto em diferentes códigos poderia resultar em uma sobrecarga de contexto e depois reduzir sua eficiência.

Nota: se implementa um mecanismo similar para as entidades que são carregadas, de modo que apenas são solicitadas os atributos utilizados (ver o método dataClass.get( )). 

List box baseado na seleção de entidades

A otimização da seleção de entidades se aplica automaticamente aos list boxes baseados ​em seleção de entidades nas configurações cliente/servidor, ao mostrar e deslocar o conteúdo de um list box. Apenas os atributos mostrados no list box são solicitados desde o servidor. Entretanto, lembre que se utiliza um contexto de otimização diferente quando se carrega a entidade atual da seleção, para não sobrecarregar o contexto de list box.

Exemplo com o 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// No método extractData, uma otimização é ativada e se associa ao contexto "shortList"
 
 $sel2:=ds.Employee.query("lastname = Sm@";$querysettings)
 $data:=extractData($sel2// No método extractData, se aplica a otimização associada ao contexto "shortList"
 
 $sel3:=ds.Employee.query("lastname = Smith";$querysettings2)
 $data:=extractDetailedData($sel3// No método extractDetailedData se desencadeia uma otimização e se associa ao contexto "longList"
 
 $sel4:=ds.Employee.query("lastname = Brown";$querysettings2)
 $data:=extractDetailedData($sel4//No método extractDetailedData, se aplica a otimização associada ao contexto "longList"

O objeto entity selection em si mesmo não pode ser copiado como um objeto:

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

Entretanto, as propriedades entity selection são numeráveis:

 ARRAY TEXT($prop;0)
 OB GET PROPERTY NAMES(ds.Employee.all();$prop)
  //$prop contém os nomes das propriedades de entity selection
  //("length", 00", "01"...)

 
PROPRIEDADES 

Produto: 4D
Tema: ORDA

 
CONTEÚDO DA PÁGINA 
 
HISTÓRIA 

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

 
ARTICLE USAGE

Manual de Desenho 4D ( 4D v19)