วิธีเติมฟิลด์เสริมผ่าน JOIN ด้วย Doctrine

สมมติว่าฉันมีเอนทิตีที่มีความสัมพันธ์ ManyToOne (กับ EXTRA_LAZY) และเห็นได้ชัดว่ามีคอลัมน์เข้าร่วม

eg. Article (main entity) -> Author (external entity)

สมมติว่าฉันเพิ่มฟิลด์ author_name ลงในบทความที่ไม่ได้แมปกับ ORM และในบางบริบท ฟิลด์นี้ควรมีค่า article->author->name (โดยปกติแล้วอาจเป็นค่าว่างได้)

เมื่อฉันค้นหารายการบทความ ฉันต้องการที่จะเติมข้อมูลนั้น article-author_name โดยอัตโนมัติ โดยไม่ต้องใช้ getter ที่ดำเนินการเลือกกับแต่ละองค์ประกอบของผลลัพธ์การสืบค้น ฉันต้องการให้ Doctrine ดึงและให้ความชุ่มชื้นกับค่านั้นด้วยการเข้าร่วมแบบง่าย ๆ ในแบบสอบถามดั้งเดิม ...

ฉันไม่ต้องการตั้งค่าโหมดการดึงข้อมูลเป็น EAGER เพื่อประสิทธิภาพเนื่องจากในโครงการผู้เขียนของฉันเป็นเอนทิตีที่ซับซ้อนมาก

เป็นไปได้ไหม?

ขอบคุณ


person Alex    schedule 02.03.2017    source แหล่งที่มา
comment
วันนี้ฉันได้ตรวจสอบคำอธิบายประกอบหลักคำสอนทั้งหมดแล้ว แต่ไม่พบคำอธิบายประกอบใดที่จะช่วยให้คุณทำเช่นนั้นได้   -  person Ihor Burlachenko    schedule 09.03.2017


คำตอบ (1)


ฉันอาจพบวิธีแก้ปัญหาแล้ว ไม่รู้ว่าเป็นวิธีที่ดีที่สุดหรือเปล่าแต่ได้ผล

ฉันได้เพิ่มฟิลด์ getter ให้กับคลาสหลักแล้ว

public getAuthorName() {
  return $this->author->name
}

ในบริบทของฉัน getter นี้จะถูกเรียกโดย serializer ในบางเงื่อนไขเท่านั้น

ในรหัสพื้นที่เก็บข้อมูลของฉันฉันมีวิธีการพิเศษ (ที่ฉันปรับโครงสร้างใหม่เพื่อให้วิธีใด ๆ สามารถเรียกมันได้โดยปริยาย) เพื่อกำหนดจำนวนประชากรของฟิลด์ Article-> author เมื่อถูกสอบถาม วิธีการนี้เพียงแค่ใช้ตัวสร้างแบบสอบถามเพื่อเพิ่ม LEFT JOIN ให้กับคลาส Author และตั้งค่า FetchMode ชั่วคราวเป็น EAGER ใน Article->author

ในตอนท้ายวิธีการเก็บข้อมูลแบบง่ายอาจเป็นเช่นนี้

public findAllWithCustomHydration() {
    $qb = $this->createQueryBuilder('obj');
    $qb->leftJoin("obj.author", "a")
       -> addSelect("a"); //add a left join and a select so the query automatically retrive all needed values to populate Article and Author entities
    //you can chain left join for nested entities like the following
    //->leftJoin("a.address", "a_address")
    //-> addSelect("a_address");


    $q = $qb->getQuery()
              ->setFetchMode(Article::class, "author", ClassMetadata::FETCH_EAGER);
   //setFetchMode + EAGER tells Doctrine to prepopulate the entites NOW and not when the getter of  $article->author is called. 
   //I don't think that line is strictly required because Doctrine could populate it at later time from the same query result or maybe doctrine automatically set the field as EAGER fetch when a LEFT JOIN is included in the query, but i've not yet tested my code without this line.

    return $q->getResult();
}

ข้อเสียคือคุณต้องปรับแต่งแต่ละคิวรีหรือใช้ DQL / SQL / QueryBuilder สำหรับแต่ละวิธีของ repo ให้ดีขึ้น แต่ด้วยการปรับโครงสร้างใหม่ที่ดี สำหรับกรณีการรวมแบบง่าย คุณสามารถเขียนวิธีทั่วไปที่ฉีดการรวมนั้นในอาร์เรย์ field_name พื้นฐาน

หวังว่าสิ่งนี้จะช่วยและเพิ่มคำตอบของคุณหากคุณพบวิธีที่ดีกว่า

ป.ล. ฉันเขียนโค้ดข้างต้นทันทีเพราะตอนนี้ฉันไม่ได้อยู่บนสมุดบันทึก หวังว่ามันจะใช้งานได้ตั้งแต่เริ่มใช้งานครั้งแรก

person Alex    schedule 12.03.2017