EntityFieldQuery vs Db_select ()

19

Dlaczego powinienem używać EntityFieldQuery, skoro mogę wykonać tę samą pracę z Db_select (), aby pobrać wartość.

Byłoby lepiej, gdyby ktoś mógł podać przykład, a nie tylko link.

j2r
źródło

Odpowiedzi:

11

Myślę, że chodzi o to, że składnia jest znacznie prostsza, a kod będzie bardziej zrozumiały.

Na przykład, jeśli chcesz, aby węzły typu my_typemiały pole o nazwie field_fooo wartości $valDb_Select, możesz zrobić coś takiego:

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

Co jest znacznie prostsze dzięki EntityFieldQuery:

$query = new EntityFieldQuery;
$entities = $query->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'my_type')
  ->fieldCondition('field_foo', 'value', $val)
  ->execute();
IcanDivideBy0
źródło
14

Myślę, że głównym powodem prefering EntityFieldQueryna db_selectto, że nie trzeba wiedzieć o strukturze niższego poziomu, innymi słowy: jak rzeczy są przechowywane w bazie danych. Poprawia to luźne połączenie .

Bart
źródło
6
Jest to poprawne, choć idzie nawet dalej. Pamięć polowa jest podłączalna. Domyślna implementacja przechowuje dane pola w osobnej tabeli dla każdego pola w bazie danych, ale można je zastąpić, istnieje na przykład implementacja, która pozwala przechowywać dane pola w MongoDB. Jeśli chcesz, aby Twój kod był przenośny i nie działał tylko w określonej konfiguracji witryny, musisz użyć EntityFieldQuery.
Berdir
3

EntityFieldQuery (EFQ) zwróci tylko identyfikatory encji. Jeśli chcesz uzyskać dostęp do danych encji, musisz zadzwonić entity_load(), co między ładowaniem danych upewni się, że wykonane zostaną wszystkie podstawowe rzeczy, na których zwykle cię nie obchodzi (takie jak ładowanie pól, wywoływanie innych modułów haków itp.) . Oczywiście skutkują to dwoma zapytaniami SQL i dużym obciążeniem, ale jest to cena, jaką trzeba zapłacić za abstrakcję.

Jeśli chodzi o bardziej przejrzystą składnię EFQ, myślę, że jest to bardziej kwestia osobistych preferencji. Ja, na przykład, czy nie uważa, że EFQ jest wyraźniejszy. Zauważ, że działający db_select()zamiennik z EFQ musi obejmować test wartości zwracanej i kolejne entity_load()wywołanie, a to dodaje dużo szumu do kodu, 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();
}

Tak więc, odpowiadając na twoje pytanie: użyj EFQ, jeśli twoje jednostki są w pełni funkcjonalne (np. Są przystosowalne, mogą być używane przez inne moduły itp.) I / lub uważasz, że ich składnia jest jaśniejsza. W innych przypadkach można użyć db_select().

Flaviovs
źródło
Nie do końca, możesz użyć podmiotu_metadanych_wrapper i uzyskać dostęp tylko do tego, czego potrzebujesz.
Kevin
Nie widzę entity_metadata_wrapper()tutaj, jak to pomaga. Nadal musisz załadować jednostkę.
flaviovs
1

EntityFieldQuery jest znacznie bardziej ograniczony niż db_select(), więc powinieneś mieć naprawdę dobry powód, aby go nie używać db_select()(patrz odpowiedź bart), który jest wystarczająco czytelny i znacznie bardziej elastyczny.

Na przykład entityFieldQueryużyj wewnętrznego przyłączenia, aby pobrać pola. Jeśli potrzebujesz LeftJoin z jakiegokolwiek powodu, jesteś uwięziony ... http://drupal.org/node/1226622

yann_yinn
źródło
Cóż, chciałbym wiedzieć, dlaczego moja odpowiedź miała „-1”. tak, entityFieldQuery jest ładniejszy, ale mniej wydajny niż db_select, który jest bardzo ładnym, solidnym i kompletnym API ... Usuwam wiele mojego bytuFieldQuery z mojego kodu, ponieważ był zbyt ograniczony do konkretnych przypadków użycia, myślę, że zdecydowanie zasługiwał na to wskazany. Tak czy siak.
yann_yinn
1
Myślę, że niektórym nie podoba się twoja odpowiedź, ponieważ nie uznaje ona, w jaki sposób entityFieldQuery jest warstwą abstrakcji ponad różnymi metodami przechowywania, co jest fajną funkcją. Pracuję na wielu stronach, w których wiemy, że, powiedzmy, MySQL zawsze będzie bazą danych dla x / y / z, a my wolimy również pisać bardziej szczere zapytania db, gdy jest to konieczne. Nie uważam, by podmiotFieldQuery był ładniejszy niż db_select. 2 porównania u góry strony są prawie wizualnie identyczne.
Charlie Schliesser,
tak, dlatego napisałem „patrz odpowiedź bart”. Z wyjątkiem tego specjalnego przypadku użycia, db_select będzie bardziej wydajny i znacznie bardziej elastyczny.
yann_yinn
Całkowicie się zgadzam.
Charlie Schliesser