EntityFieldQuery INNER JOIN

21

Me gustaría ejecutar una consulta con el objeto EntityFieldQuery. Necesito valor de la tabla node y node_access, por lo tanto, necesito usar INNER JOIN. De la documentación do no puedo entender cómo es esto posible.

Esto es lo que tengo:

$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
fuente
1
Aunque no se puede hacer sobre la marcha en Drupal 7, se puede hacer en Drupal 8 (no publicado en el momento de escribir este artículo). Consulte la consulta sobre el campo de la entidad para obtener más detalles (incluido un ejemplo).
colan
En Drupal 8 todas las condiciones son así (-> condición ()). Ex de un EFQ en D8: $ result = \ Drupal :: entityQuery ('node') -> condition ('type', array ('entity_a', 'entity_b'), 'entity'b),' IN ') -> condition (' status ' , NODE_PUBLISHED) -> condition ('field_myfield.value', '5', '=') -> execute (); En Drupal 8 EFQ, la columna se define directamente en el campo de nombre por field_name.value o field_name.target_id en drupal 7 es->fieldCondition('field_name', 'target_id', $entities_a, 'IN');
woprrr

Respuestas:

30

No puede agregar uniones adicionales a un EntityFieldQuerydirectamente (no es compatible), pero podría agregar una etiqueta a la consulta, implementar hook_query_TAG_alter()y agregar la unión manualmente cuando la consulta se convierte en una consulta db estándar.

Esto no se ha probado, pero probablemente lo llevará a la mayor parte del camino:

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

// get the query results as normal

Y luego la función de consulta alter:

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

La otra forma de hacerlo sería subclasificar EntityFieldQueryy agregar la unión, pero creo que el método anterior es más simple en este caso.

Clive
fuente
¿Hay una mejor manera de hacerlo en una sola función? Incluso si no es asíEntityFieldQuery
Allan Thomas
2
En realidad no, la única otra forma es construir la consulta manualmente usando db_select, entonces puedes tener tanto control como quieras sobre ella
Clive
Iré con eso. Thx
Allan Thomas
@Clive ... oh, esta respuesta es realmente interesante. Gusta. : P
tenken
2
@Michiel No EntityFieldQueryno almacena en caché, simplemente envuelve SelectQueryy agrega algunos métodos para las entidades. Esos métodos adicionales explican la disminución leve (muy leve) del rendimiento que experimentaría al usarlo en lugar de un uso regularSelectQuery
Clive
3

Si está utilizando propiedades personalizadas con sus propias tablas, el método de etiqueta no funcionará. Necesita usar subconsultas en su lugar:

$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 ¿ Necesita unirse a una EntityFieldQuery, qué tal una subconsulta? para detalles.

colan
fuente
Excelente solución para casos como el mío, con tablas personalizadas. ¡Impresionante trabajo!
Ignacio Segura Postigo