EntityFieldQuery INNER JOIN


21

Vorrei eseguire una query utilizzando l'oggetto EntityFieldQuery. Ho bisogno di valore sia dalla tabella node che node_access quindi dovrei usare INNER JOIN. Dalla documentazione do non riesco a capire come sia possibile.

Ecco cosa ho -

$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
Anche se non può essere fatto al volo in Drupal 7, può essere fatto in Drupal 8 (non pubblicato al momento in cui scrivo). Vedere la query Campo entità ha ottenuto il supporto join per i dettagli (incluso un esempio).
colan,

In Drupal 8 tutte le condizioni sono così (-> condizione ()). Ex di un EFQ in D8: $ result = \ Drupal :: entityQuery ('node') -> condition ('type', array ('entity_a', 'entity_b'), 'IN') -> condition ('status' , NODE_PUBLISHED) -> condition ('field_myfield.value', '5', '=') -> execute (); In Drupal 8 EFQ la colonna è definita direttamente nel campo nome da field_name.value o field_name.target_id in drupal 7 is->fieldCondition('field_name', 'target_id', $entities_a, 'IN');
woprrr

Risposte:


30

Non è possibile aggiungere altri join EntityFieldQuerydirettamente a (non è supportato), ma è possibile aggiungere un tag alla query, implementare hook_query_TAG_alter()e aggiungere il join manualmente quando la query viene convertita in una query db standard.

Questo non è testato ma probabilmente ti porterà la maggior parte del modo lì:

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

// get the query results as normal

E poi la funzione di modifica della query:

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

L'altro modo per farlo sarebbe quello di sottoclassare EntityFieldQueryse stesso e aggiungere il join, ma penso che il metodo sopra descritto sia più semplice in questo caso.


C'è un modo migliore per farlo in una singola funzione? Anche se non lo èEntityFieldQuery
Allan Thomas il

2
Non proprio, l'unico altro modo è costruire manualmente la query usando db_select, quindi puoi avere tutto il controllo che vuoi su di essa
Clive

Vado con quello. Grazie
Allan Thomas il

@Clive ... oh questa risposta è davvero interessante. Mi piace. : P
Tenken,

2
@Michiel No EntityFieldQuerynon esegue alcuna memorizzazione nella cache, si avvolge solo attorno a SelectQuerye aggiunge alcuni metodi per le entità. Quei metodi extra spiegano la leggera (leggerissima) riduzione delle prestazioni che sperimenteresti usando invece di un normaleSelectQuery
Clive

3

Se stai utilizzando proprietà personalizzate con le tue tabelle, il metodo tag non funzionerà. Devi invece utilizzare le subquery:

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

Vedi Hai bisogno di un join in un EntityFieldQuery, che ne dici di una subquery? per dettagli.


Ottima soluzione per casi come il mio, con tavoli personalizzati. Ottimo lavoro!
Ignacio Segura Postigo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.