EntityFieldQuery vs Db_select ()


19

Perché dovrei usare EntityFieldQuery quando posso fare lo stesso lavoro con Db_select () per recuperare il valore.

Sarebbe meglio se qualcuno potesse fornire un esempio, non solo un collegamento.

Risposte:


11

Penso che il punto sia che la sintassi è molto più semplice e il codice sarà più comprensibile.

Ad esempio, se vuoi nodi con tipo my_typeche hanno un campo chiamato field_foocon il valore $val, con Db_Select, fai qualcosa come:

$nids = db_select('node', 'n')
  ->fields('n', array('nid'))
  ->join('field_data_field_foo', 'foo', 'foo.entity_id = n.nid')
  ->condition('n.type', 'my_type')
  ->condition('foo.field_foo_value', $val)
  ->execute()->fetchCol();

Che è molto più semplice con EntityFieldQuery:

$query = new EntityFieldQuery;
$entities = $query->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'my_type')
  ->fieldCondition('field_foo', 'value', $val)
  ->execute();

14

Penso che il motivo principale abbiamo preferito EntityFieldQuerysopra db_selectè che non c'è bisogno di conoscere la struttura di livello inferiore, in altre parole: come roba è memorizzato nel database. Questo migliora l' accoppiamento libero .


6
Questo è corretto, anche se va oltre. La memoria di campo è collegabile. L'implementazione predefinita archivia i dati dei campi in una tabella separata per campo nel database, ma può essere sostituita, ad esempio esiste un'implementazione che consente di archiviare i dati dei campi in MongoDB. Se vuoi che il tuo codice sia portatile e non funzioni solo sulla tua specifica configurazione del sito, devi usare EntityFieldQuery.
Berdir,

3

EntityFieldQuery (EFQ) restituirà solo gli ID entità. Se vuoi accedere ai dati delle entità, dovrai chiamare entity_load(), che, tra il caricamento dei dati, farà in modo che vengano fatte tutte le cose sottostanti che normalmente non ti interessano (come il caricamento di campi, la chiamata di hook di altri moduli ecc.) . Ovviamente, questo comporta due query SQL e un sacco di costi generali, ma questo è il prezzo da pagare per l'astrazione.

Per quanto riguarda la sintassi EFQ essendo più chiara, penso che sia molto più una questione di preferenze personali. Ad esempio, non credo che l'EFQ sia più chiaro. Si noti che un db_select()sostituto funzionante con EFQ deve includere il test del valore di ritorno e la entity_load()chiamata successiva e questo aggiunge molto rumore al codice, IMHO:

$query = new EntityFieldQuery();
$entities = $query->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'my_type')
  ->fieldCondition('field_foo', 'value', $val)
  ->execute();
if (!empty($entities['node'])) {
  $nodes = entity_load('node', array_keys($entities['node']));
} else {
  $nodes = array();
}

Quindi, rispondendo alla tua domanda: usa EFQ se le tue entità sono full optional (ad esempio sono fieldable, possono essere utilizzate da altri moduli, ecc.) E / o pensi che la sua sintassi sia più chiara. Se altri casi, è possibile utilizzare db_select().


Non esattamente, puoi usare entity_metadata_wrapper e accedere solo a ciò di cui hai bisogno.
Kevin,

Non riesco a vedere come entity_metadata_wrapper()aiuta qui. Devi ancora caricare l'entità.
Flaviov

1

EntityFieldQuery è molto più limitato di db_select(), quindi dovresti avere davvero un buon motivo per non usarlo db_select()(vedi risposta al bart), che è abbastanza leggibile e molto più flessibile.

Ad esempio, entityFieldQueryutilizzare innerJoin per recuperare i campi. Se hai bisogno di un LeftJoin per qualsiasi motivo, sei intrappolato ... http://drupal.org/node/1226622


Bene, vorrei sapere perché il mio anwser aveva un "-1". sì, entityFieldQuery è più bello, ma meno efficiente di db_select che è un'API molto bella, robusta e completa ... rimuovo molta mia entitàFieldQuery dal mio codice perché era troppo limitata per casi d'uso specifici, penso che meritasse sicuramente di essere sottolineato. Comunque.
yann_yinn,

1
Penso che ad alcuni non piaccia la tua risposta perché non riesce a riconoscere come entityFieldQuery è un livello di astrazione al di sopra di diversi metodi di archiviazione, che è una caratteristica interessante. Lavoro su molti siti in cui sappiamo che, per esempio, MySQL sarà sempre il database per x / y / z e preferiamo anche scrivere query db più snelle quando ne abbiamo bisogno. Non trovo entityFieldQuery più carino di db_select. I 2 confronti nella parte superiore della pagina sono quasi visivamente identici.
Charlie Schliesser,

sì, ecco perché ho scritto "vedi risposta bart". Ad eccezione di questo caso d'uso speciale, db_select sarà più efficiente e molto più flessibile.
yann_yinn,

Sono completamente d'accordo.
Charlie Schliesser,
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.