EntityFieldQuery против Db_select ()

19

Почему я должен использовать EntityFieldQuery, когда я могу сделать ту же работу с Db_select (), чтобы получить значение.

Было бы лучше, если бы кто-то мог привести пример, а не только ссылку.

j2r
источник

Ответы:

11

Я думаю, что дело в том, что синтаксис намного проще, и код будет более понятным.

Например, если вы хотите, чтобы узлы с типом , чье my_typeполе имело значение field_fooсо значением $val, с помощью Db_Select, yuoll делают что-то вроде:

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

Что намного проще с EntityFieldQuery:

$query = new EntityFieldQuery;
$entities = $query->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'my_type')
  ->fieldCondition('field_foo', 'value', $val)
  ->execute();
IcanDivideBy0
источник
14

Я думаю , что главная причина желаемая EntityFieldQueryнад db_selectтом , что вы не должны знать о структуре нижнего уровня, другими словами: как материал хранится в базе данных. Это улучшает слабую связь .

Барт
источник
6
Это правильно, хотя идет еще дальше. Поле для хранения является подключаемым. Реализация по умолчанию хранит полевые данные в отдельной таблице для каждого поля в базе данных, но ее можно заменить, например, существует реализация, которая позволяет хранить полевые данные в MongoDB. Если вы хотите, чтобы ваш код был переносимым, а не просто работал с конкретной конфигурацией вашего сайта, вы должны использовать EntityFieldQuery.
Бердир
3

EntityFieldQuery (EFQ) будет возвращать только идентификаторы сущностей. Если вы хотите получить доступ к данным сущностей, вам придется вызывать их entity_load(), что, помимо загрузки данных, позволит убедиться, что все базовые вещи, которые вам обычно не нужны (такие как загрузка полей, вызов других модулей и т. Д.), Выполнены , Конечно, это приводит к двум запросам SQL и большим накладным расходам, но это цена, которую нужно заплатить за абстракцию.

Что касается синтаксиса EFQ, более понятного, я думаю, что это гораздо больше вопрос личных предпочтений. Я, например, не думаю, что EFQ понятнее. Обратите внимание, что рабочая db_select()замена с EFQ должна включать проверку возвращаемого значения и последующий entity_load()вызов, и это добавляет много шума в код, 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();
}

Итак, отвечая на ваш вопрос: используйте EFQ, если ваши сущности являются полнофункциональными (например, могут использоваться в полевых условиях, могут использоваться другими модулями и т. Д.) И / или вы считаете, что его синтаксис более понятен. Если другие случаи, использование может использовать db_select().

flaviovs
источник
Не совсем, вы можете использовать entity_metadata_wrapper и получить доступ только к тому, что вам нужно.
Кевин
Я не вижу, как entity_metadata_wrapper()помогает здесь. Вам все еще нужно загрузить объект.
flaviovs
1

EntityFieldQuery гораздо более ограничен db_select(), поэтому у вас должна быть действительно веская причина не использовать db_select()(см. Ответ Барта), которая достаточно читабельна и гораздо более гибкая.

Например, entityFieldQueryиспользуйте innerJoin для извлечения полей. Если вам нужен левый джойн по какой-либо причине, вы попали в ловушку ... http://drupal.org/node/1226622

yann_yinn
источник
Хорошо, я хотел бы знать, почему у моего ответа был "-1". да, entityFieldQuery красивее, но менее эффективен, чем db_select, который является очень хорошим, надежным и полным API ... Я удаляю большую часть моего entityFieldQuery из моего кода, потому что он был слишком ограничен для конкретных случаев использования, думаю, что он определенно заслуживает того, чтобы указал. Тем не мение.
yann_yinn
1
Я думаю, что некоторым не нравится ваш ответ, потому что он не в состоянии признать, что entityFieldQuery - это уровень абстракции над различными методами хранения, что является интересной функцией. Я работаю на многих сайтах, где мы знаем, что, скажем, MySQL всегда будет базой данных для x / y / z, и мы также предпочитаем писать более гибкие запросы БД, когда это необходимо. Я не считаю, что entityFieldQuery более красив, чем db_select. 2 сравнения в верхней части страницы практически идентичны.
Чарли Шлиссер
да, именно поэтому я написал "см. ответ Барта". За исключением этого специального варианта использования, db_select будет более эффективным и гораздо более гибким.
yann_yinn
Я полностью согласен.
Чарли Шлиссер