EntityFieldQuery vs Db_select ()

19

Pourquoi devrais-je utiliser EntityFieldQuery quand je peux faire le même travail avec Db_select () pour récupérer la valeur.

Il serait préférable que quelqu'un puisse fournir un exemple, pas seulement un lien.

j2r
la source

Réponses:

11

Je pense que le fait est que la syntaxe est beaucoup plus simple et que le code sera plus compréhensible.

Par exemple, si vous voulez des nœuds de type my_typequi ont un champ nommé field_fooavec la valeur $val, avec Db_Select, yuoll fait quelque chose comme:

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

Ce qui est beaucoup plus simple avec EntityFieldQuery:

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

Je pense que la raison principale préférant EntityFieldQueryplus db_selectest que vous ne devez pas connaître la structure de niveau inférieur, en d' autres termes: comment les choses sont stockées dans la base de données. Cela améliore le couplage lâche .

Bart
la source
6
C'est exact, même si cela va encore plus loin. Le stockage sur le terrain est enfichable. L'implémentation par défaut stocke les données de champ dans une table distincte par champ dans la base de données, mais elle peut être remplacée, il existe par exemple une implémentation qui permet de stocker les données de champ dans MongoDB. Si vous souhaitez que votre code soit portable et ne fonctionne pas uniquement sur la configuration de votre site spécifique, vous devez utiliser EntityFieldQuery.
Berdir
3

EntityFieldQuery (EFQ) ne renverra que les ID d'entité. Si vous souhaitez accéder aux données des entités, vous devrez appelerentity_load() , ce qui, parmi le chargement des données, fera en sorte que toutes les choses sous-jacentes qui ne vous intéressent pas normalement (comme le chargement des champs, l'appel d'autres hooks de modules, etc.) soient faites . Bien sûr, cela entraîne deux requêtes SQL et beaucoup de frais généraux, mais c'est le prix à payer pour l'abstraction.

Quant à la syntaxe EFQ étant plus claire, je pense que c'est beaucoup plus une question de préférences personnelles. Par exemple, je ne pense pas que l'EFQ soit plus clair. Notez qu'un db_select()remplacement de travail avec EFQ doit inclure le test de valeur de retour et l' entity_load()appel suivant, et cela ajoute beaucoup de bruit au code, à mon humble avis :

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

Donc, pour répondre à votre question: utilisez EFQ si vos entités sont complètes (par exemple sont modifiables, peuvent être utilisées par d'autres modules, etc.) et / ou vous pensez que sa syntaxe est plus claire. Si d'autres cas, l'utilisation peut utiliser db_select().

flaviovs
la source
Pas exactement, vous pouvez utiliser entity_metadata_wrapper et accéder uniquement à ce dont vous avez besoin.
Kevin
Je ne vois pas comment l' entity_metadata_wrapper()aide ici. Vous devez toujours charger l'entité.
flaviovs
1

EntityFieldQuery est beaucoup plus limité que db_select(), donc vous devriez avoir une très bonne raison de ne pas l'utiliser db_select()(voir la réponse de Bart), qui est suffisamment lisible et beaucoup plus flexible.

Par exemple, entityFieldQueryutilisez innerJoin pour récupérer des champs. Si vous avez besoin d'un leftJoin pour une raison quelconque, vous êtes pris au piège ... http://drupal.org/node/1226622

yann_yinn
la source
Eh bien, je voudrais savoir pourquoi ma réponse avait un "-1". oui, entityFieldQuery est plus joli, mais moins efficace que db_select qui est une API très agréable, robuste et complète ... Je supprime beaucoup de mon entityFieldQuery de mon code car il était trop limité pour des cas d'utilisation spécifiques, je pense qu'il méritait vraiment d'être souligné. En tous cas.
yann_yinn
1
Je pense que certains n'aiment pas votre réponse car elle ne reconnaît pas comment entityFieldQuery est une couche d'abstraction au-dessus de différentes méthodes de stockage, ce qui est une fonctionnalité intéressante. Je travaille sur de nombreux sites où nous savons que, disons, MySQL sera toujours la base de données pour x / y / z et nous préférons également écrire des requêtes db plus légères quand nous en avons besoin. Je ne trouve pas entityFieldQuery plus joli que db_select. Les 2 comparaisons en haut de la page sont presque identiques visuellement.
Charlie Schliesser
oui, c'est pourquoi j'ai écrit "voir la réponse de Bart". À l'exception de ce cas d'utilisation spécial, db_select sera plus efficace et beaucoup plus flexible.
yann_yinn
Je suis complètement d'accord.
Charlie Schliesser