Чому я повинен використовувати EntityFieldQuery, коли я можу виконати ту саму роботу з Db_select (), щоб отримати значення.
Було б краще, якщо хтось може навести приклад, а не лише посилання.
Чому я повинен використовувати EntityFieldQuery, коли я можу виконати ту саму роботу з Db_select (), щоб отримати значення.
Було б краще, якщо хтось може навести приклад, а не лише посилання.
Відповіді:
Я думаю, сенс у тому, що синтаксис набагато простіший, а код буде більш зрозумілим.
Наприклад, якщо ви хочете, щоб вузли з типом 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();
Я думаю , що головна причина бажана EntityFieldQuery
над db_select
те , що ви не повинні знати про структуру нижнього рівня, іншими словами: як матеріал зберігається в базі даних. Це покращує нещільне з'єднання .
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()
.
entity_metadata_wrapper()
тут допомагає. Ще потрібно завантажити сутність.
EntityFieldQuery набагато обмеженіший db_select()
, тому у вас повинен бути справді вагомий привід не використовувати db_select()
(див. Відповідь барта), який є читабельним і набагато гнучкішим.
Наприклад, entityFieldQuery
використовуйте innerJoin для отримання полів. Якщо вам потрібна leftJoin з будь-якої причини, ви потрапили в пастку ...
http://drupal.org/node/1226622