का उपयोग नहीं करेगा मेरे पास Car
इकाई है जो एक इकाई Owner
के साथ कई से एक रिश्ते के साथ है। यदि मैं सभी कारों का चयन करता हूं, तो सिद्धांत Car
तालिका पर एक प्रश्न पूछता है, और बाद में प्रत्येक कार के लिए Owner
तालिका पर एक क्वेरी करता है। तो Car
और Owner
तालिकाओं के बीच एक एकल जॉइन क्वेरी के बजाय एन कारें एन + 1 क्वेरी प्राप्त करती हैं।Doctrine2 कई-से-एक एसोसिएशन जॉइन क्वेरी
/** @Entity */
class Car {
/** @Id @Column(type="smallint") */
private $id;
/** @ManyToOne(targetEntity="Owner", fetch="EAGER")
@JoinColumn(name="owner", referencedColumnName="id") */
private $owner;
public function getId() { return $this->id; }
public function getOwner() { return $this->owner; }
}
/** @Entity */
class Owner {
/** @Id @Column(type="smallint") */
private $id;
/** @Column(type="string") */
private $name;
public function getName() { return $this->name; }
}
मैं उनके मालिकों के साथ कारों की सूची चाहते हैं, मुझे क्या करना:
$repo = $em->getRepository('Car');
$cars = $repo->findAll();
foreach($cars as $car)
echo 'Car no. ' . $car->getId() .
' owned by ' . $car->getOwner()->getName() . '\n';
अब यह सब बहुत अच्छी तरह से तथ्य यह है कि से काम करता है, के अलावा
मेरे संस्थाओं इस प्रकार हैं सिद्धांत प्रत्येक कार के लिए एक प्रश्न जारी करता है।
SELECT * FROM Car;
SELECT * FROM Owner WHERE id = 1;
SELECT * FROM Owner WHERE id = 2;
SELECT * FROM Owner WHERE id = 3;
....
बेशक मैं इस तरह देखने के लिए मेरी क्वेरी लॉग चाहते हैं:
SELECT * FROM Car JOIN Owner ON Car.owner = Owner.id;
चाहे मैं fetch="EAGER"
या fetch="LAZY"
कोई फर्क नहीं पड़ता है, और मुझे शामिल हों के साथ एक कस्टम DQL क्वेरी बनाने भले ही दो इकाइयों के बीच, $car->getOwner()
अभी भी सिद्धांत को डेटाबेस से पूछताछ करने का कारण बनता है (जब तक कि मैं ईगर का उपयोग नहीं करता, उस स्थिति में $repo->findAll()
उन सभी का कारण बनता है)।
क्या मैं यहां बहुत थक गया हूं, और यह जिस तरह से काम करना है - या क्या इसके बजाय जॉइन क्वेरी करने के लिए सिद्धांत को मजबूर करने का एक चालाक तरीका है?
ऐसा लगता है कि वह भी 2. x में मामला है मैंने पूछताछ की कोशिश की थी 'कार सी जॉइन सी। जॉइनर ओ' से चुनें, जो अभी भी एन + 1 प्रश्न बना है, लेकिन आपका काम ठीक है। बहुत धन्यवाद! मुझे लगता है कि मुझे findXxx विधियों का उपयोग न करने के साथ बस रहना होगा। – Frode
इस तरह की सुविधा विधियों के लिए, मैं एक "सेवा परत" या "भंडार" शैली वर्ग बनाने का सुझाव दूंगा जो मॉडलों को लोड करने जैसे कार्यों को संभालता है। इस तरह आप पूरे स्थान पर डीक्यूएल तर्क को डुप्लिकेट किए बिना क्वेरी को आसानी से पुन: उपयोग कर सकते हैं। –