EntityFieldQuery INNER JOIN

21

Ich möchte eine Abfrage mit dem EntityFieldQuery-Objekt ausführen. Ich benötige Werte aus der Tabelle node und node_access, daher muss INNER JOIN verwendet werden. Aus der Do-Dokumentation kann ich nicht herausfinden, wie dies möglich ist.

Folgendes habe ich -

$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
quelle
1
Obwohl dies in Drupal 7 nicht im laufenden Betrieb möglich ist, ist dies in Drupal 8 möglich (zum Zeitpunkt der Veröffentlichung noch nicht veröffentlicht). Weitere Informationen (einschließlich eines Beispiels) finden Sie unter Entitätsfeldabfrage hat Join-Unterstützung .
Colan
In Drupal 8 sind alle Bedingungen wie folgt (-> condition ()). Beispiel eines EFQ in D8: $ result = \ Drupal :: entityQuery ('node') -> Bedingung ('type', Array ('entity_a', 'entity_b'), 'IN') -> Bedingung ('status') , NODE_PUBLISHED) -> Bedingung ('field_myfield.value', '5', '=') -> execute (); In Drupal 8 EFQ wird die collumn direkt im Namensfeld von field_name.value oder field_name.target_id in Drupal 7 definiert ist->fieldCondition('field_name', 'target_id', $entities_a, 'IN');
woprrr

Antworten:

30

Sie können einer EntityFieldQuerydirekten hook_query_TAG_alter()Verknüpfung keine zusätzlichen Verknüpfungen hinzufügen (dies wird nicht unterstützt), Sie können jedoch der Abfrage ein Tag hinzufügen, die Verknüpfung implementieren und manuell hinzufügen, wenn die Abfrage in eine Standard-DB-Abfrage konvertiert wird.

Dies ist nicht getestet, wird aber wahrscheinlich den größten Teil des Weges dorthin bringen:

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

// get the query results as normal

Und dann die Abfrageänderungsfunktion:

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

Die andere Möglichkeit besteht darin, sich selbst in Unterklassen zu unterteilen EntityFieldQueryund den Join hinzuzufügen, aber ich denke, dass die obige Methode in diesem Fall einfacher ist.

Clive
quelle
Gibt es einen besseren Weg, dies in einer einzigen Funktion zu tun? Auch wenn es nicht istEntityFieldQuery
Allan Thomas
2
Nicht wirklich, die einzige andere Möglichkeit besteht darin, die Abfrage manuell mithilfe von aufzubauen. db_selectDann können Sie so viel Kontrolle darüber haben, wie Sie möchten
Clive
Ich werde damit weitermachen. Thx
Allan Thomas
@Clive ... oh diese Antwort ist wirklich interessant. Mag ich. : P
tenken 05.10.12
2
@Michiel Nein EntityFieldQueryführt kein Caching durch, sondern umschließt nur a SelectQueryund fügt einige Methoden für Entitäten hinzu. Diese zusätzlichen Methoden erklären den geringfügigen (sehr geringfügigen) Leistungsabfall, den Sie bei der Verwendung feststellen würden, im Gegensatz zu einem regulärenSelectQuery
Clive
3

Wenn Sie benutzerdefinierte Eigenschaften mit Ihren eigenen Tabellen verwenden, funktioniert die Tag-Methode nicht. Sie müssen stattdessen Unterabfragen verwenden:

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

Siehe Benötigen Sie einen Join in einer EntityFieldQuery? Wie wäre es mit einer Unterabfrage? für Details.

colan
quelle
Hervorragende Lösung für Fälle wie meine, mit benutzerdefinierten Tabellen. Gute Arbeit!
Ignacio Segura Postigo