EntityFieldQuery เทียบกับ Db_select ()


19

เหตุใดฉันจึงควรใช้EntityFieldQueryเมื่อฉันสามารถทำงานเดียวกันกับDb_select ()เพื่อดึงค่า

มันจะดีกว่าถ้ามีคนสามารถให้ตัวอย่างไม่ใช่แค่ลิงค์

คำตอบ:


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

14

ฉันคิดว่าเหตุผลหลักที่นิยมใช้EntityFieldQueryมากกว่าdb_selectก็คือคุณไม่จำเป็นต้องรู้เกี่ยวกับโครงสร้างระดับล่างอีกนัยหนึ่ง: วิธีจัดเก็บข้อมูลในฐานข้อมูล นี้จะช่วยปรับปรุงcoupling หลวม


6
สิ่งนี้ถูกต้องแม้ว่ามันจะดำเนินต่อไป ที่เก็บข้อมูลภาคสนามเป็นแบบเสียบได้ การนำไปใช้งานเริ่มต้นจะเก็บข้อมูลของเขตข้อมูลในตารางแยกต่างหากต่อเขตข้อมูลในฐานข้อมูล แต่สามารถแทนที่ได้ตัวอย่างเช่นการใช้งานที่ช่วยให้สามารถเก็บข้อมูลภาคสนามใน MongoDB ได้ หากคุณต้องการให้รหัสของคุณเป็นแบบพกพาและไม่เพียง แต่ทำงานบนการกำหนดค่าไซต์ของคุณโดยเฉพาะคุณต้องใช้ EntityFieldQuery
Berdir

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()ได้


ไม่อย่างแน่นอนคุณสามารถใช้ entity_metadata_wrapper และเข้าถึงเฉพาะสิ่งที่คุณต้องการ
Kevin

ฉันล้มเหลวในการดูว่ามีอะไรentity_metadata_wrapper()ที่นี่ คุณยังต้องโหลดเอนทิตี
flaviovs

1

EntityFieldQueryมีข้อ จำกัด มากกว่าdb_select()ดังนั้นคุณควรมีเหตุผลที่ดีที่จะไม่ใช้db_select()(ดูคำตอบของบาร์ต) ซึ่งอ่านได้ง่ายและยืดหยุ่นมากขึ้น

ตัวอย่างเช่นentityFieldQueryใช้innerJoinเพื่อดึงข้อมูลฟิลด์ หากคุณต้องการซ้ายเข้าร่วมด้วยเหตุผลใดก็ตามคุณติดกับ ... http://drupal.org/node/1226622


ฉันอยากรู้ว่าทำไม anwser ของฉันจึงมี "-1" ใช่ entityFieldQuery น่ารักกว่า แต่มีประสิทธิภาพน้อยกว่า db_select ซึ่งเป็น API ที่ดีน่าเชื่อถือและสมบูรณ์ ... ฉันลบ entityFieldQuery ของฉันออกจากรหัสของฉันเพราะมันมีข้อ จำกัด มากเกินไปสำหรับกรณีการใช้งานเฉพาะคิดว่าสมควรได้รับอย่างแน่นอน ชี้ให้เห็น. อย่างไรก็ตาม.
yann_yinn

1
ฉันคิดว่าบางคนไม่ชอบคำตอบของคุณเพราะล้มเหลวในการรับทราบว่า entityFieldQuery เป็นเลเยอร์นามธรรมเหนือวิธีการจัดเก็บข้อมูลที่แตกต่างกันซึ่งเป็นคุณสมบัติที่ยอดเยี่ยม ฉันทำงานในเว็บไซต์จำนวนมากที่เรารู้ว่าพูด MySQL จะเป็นฐานข้อมูลสำหรับ x / y / z และเรายังต้องการเขียนแบบสอบถาม db lean เมื่อเราต้องการ ฉันไม่พบ entityFieldQuery ให้ดีกว่า db_select การเปรียบเทียบ 2 รายการที่ด้านบนของหน้าเกือบเหมือนกัน
Charlie Schliesser

ใช่นั่นเป็นเหตุผลที่ฉันเขียนว่า "เห็นคำตอบบาร์ต" ยกเว้นกรณีการใช้งานพิเศษนี้ db_select จะมีประสิทธิภาพมากขึ้นและมีความยืดหยุ่นมากกว่า
yann_yinn

ฉันเห็นด้วยอย่างยิ่ง
Charlie Schliesser
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.