EntityFieldQuery INNER JOIN


21

Je voudrais exécuter une requête à l'aide de l'objet EntityFieldQuery. J'ai besoin de valeur à la fois du nœud et de la table node_access, donc j'aurais besoin d'utiliser INNER JOIN. À partir de la documentation do, je ne peux pas comprendre comment cela est possible.

Voici ce que j'ai -

$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();

1
Bien que cela ne puisse pas être fait à la volée dans Drupal 7, cela peut être fait dans Drupal 8 (non publié au moment d'écrire ces lignes). Voir la requête Entity Field a obtenu la prise en charge des jointures pour plus de détails (y compris un exemple).
colan

Dans Drupal 8, toutes les conditions sont comme ça (-> condition ()). Ex d'un EFQ en D8: $ result = \ Drupal :: entityQuery ('node') -> condition ('type', array ('entity_a', 'entity_b'), 'IN') -> condition ('status' , NODE_PUBLISHED) -> condition ('field_myfield.value', '5', '=') -> execute (); Dans Drupal 8 EFQ, la colonne est définie directement dans le champ nom par field_name.value ou field_name.target_id dans drupal 7 is->fieldCondition('field_name', 'target_id', $entities_a, 'IN');
woprrr

Réponses:


30

Vous ne pouvez pas ajouter de jointures supplémentaires à un EntityFieldQuerydirectement (ce n'est pas pris en charge), mais vous pouvez ajouter une balise à la requête, implémenter hook_query_TAG_alter()et ajouter la jointure manuellement lorsque la requête est convertie en une requête db standard.

Ce n'est pas testé, mais vous obtiendrez probablement la plupart du chemin:

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

// get the query results as normal

Et puis la fonction alter alter:

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

L'autre façon de le faire serait de se sous EntityFieldQuery- classer et d'ajouter la jointure, mais je pense que la méthode ci-dessus est plus simple dans ce cas.


Existe-t-il une meilleure façon de le faire dans une seule fonction? Même si ce n'est pas le casEntityFieldQuery
Allan Thomas

2
Pas vraiment, la seule autre façon est de construire la requête manuellement en utilisant db_select, alors vous pouvez avoir autant de contrôle que vous le souhaitez
Clive

J'irai avec ça. Thx
Allan Thomas

@Clive ... oh cette réponse est vraiment intéressante. J'aime ça. : P
tenken

2
@Michiel No EntityFieldQueryne fait aucune mise en cache, il s'enroule simplement autour de a SelectQueryet ajoute quelques méthodes pour les entités. Ces méthodes supplémentaires expliquent la légère (très légère) diminution des performances que vous ressentiriez en l'utilisant par opposition à une régulièreSelectQuery
Clive

3

Si vous utilisez des propriétés personnalisées avec vos propres tables, la méthode des balises ne fonctionnera pas. Vous devez utiliser des sous-requêtes à la place:

$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');

Voir Besoin d'une jointure dans une EntityFieldQuery, que diriez-vous d'une sous-requête? pour plus de détails.


Excellente solution pour des cas comme le mien, avec des tables personnalisées. Super travail!
Ignacio Segura Postigo
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.