EntityFieldQuery INNER JOIN

21

Eu gostaria de executar uma consulta usando o objeto EntityFieldQuery. Eu preciso de valor da tabela node e node_access, portanto, eu precisaria usar INNER JOIN. Na documentação do do, não consigo descobrir como isso é possível.

Aqui está o que eu tenho -

$query = new EntityFieldQuery();
$result = $query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'node_access')
->propertyCondition('type', 'external_link')
->propertyCondition('status', 1)
->fieldCondition('gid', '3', '=')
->fieldCondition('realm', 'domain_id', '=')
->fieldCondition('grant_view', '1', '>=')
->range(0,1)
->execute();
Allan Thomas
fonte
11
Embora não possa ser feito on-the-fly no Drupal 7, ele pode ser feito no Drupal 8 (não lançado no momento em que este artigo foi escrito). Consulte A consulta do campo de entidade obteve suporte à junção para obter detalhes (incluindo um exemplo).
Colan
No Drupal 8, todas as condições são assim (-> condição ()). Ex de um EFQ em D8: $ result = \ Drupal :: entityQuery ('nó') -> condição ('tipo', matriz ('entidade_a', 'entidade_b'), 'IN') -> condição ('status' , NODE_PUBLISHED) -> condição ('field_myfield.value', '5', '=') -> execute (); No Drupal 8 EFQ o collumn é definido directamente no campo nome por field_name.value ou field_name.target_id em Drupal 7 é->fieldCondition('field_name', 'target_id', $entities_a, 'IN');
woprrr

Respostas:

30

Você não pode adicionar associações extras a um EntityFieldQuerydiretamente (não é suportado), mas pode adicionar uma marca à consulta, implementar hook_query_TAG_alter()e adicionar a associação manualmente quando a consulta é convertida em uma consulta db padrão.

Isso não foi testado, mas provavelmente o levará até o final:

$query = new EntityFieldQuery;
$query->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'node_access')
  // etc
  ->addTag('MYTAG');

// get the query results as normal

E então a consulta altera a função:

function MYDMOULE_query_MYTAG_alter(QueryAlterableInterface $query) {
  $query->join('node_access', 'node_access', 'node_access.nid = node.nid');
}

A outra maneira de fazer isso seria subclassificar- EntityFieldQueryse e adicionar a junção, mas acho que o método acima é mais simples nesse caso.

Clive
fonte
Existe uma maneira melhor de fazer isso em uma única função? Mesmo que não sejaEntityFieldQuery
Allan Thomas
2
Na verdade, a única outra maneira é criar a consulta manualmente usando db_select, então você pode ter o controle que quiser sobre ela
Clive
Eu vou com isso. Thx
Allan Thomas
@ Clive ... oh, esta resposta é realmente interessante. Gosto disso. : P
tenken
2
@ Michel No EntityFieldQuerynão faz nenhum cache, apenas envolve um SelectQuerye adiciona alguns métodos para entidades. Esses métodos extra explicar a ligeira (muito ligeira) redução de desempenho você experiência de usá-lo em oposição a um regularSelectQuery
Clive
3

Se você estiver usando propriedades personalizadas com suas próprias tabelas, o método tag não funcionará. Você precisa usar subconsultas:

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'user');

$roles_subquery = db_select('users_roles', 'ur');
$roles_subquery->fields('ur', array('uid'));
$roles_subquery->condition('rid', $my_role_id);

$query->propertyCondition('uid', $roles_subquery, 'IN');

Consulte Precisa de uma associação em uma EntityFieldQuery, que tal uma subconsulta? para detalhes.

colan
fonte
Excelente solução para casos como o meu, com tabelas personalizadas. Otimo trabalho!
Ignacio Segura Postigo