के साथ कई से कई संगठनों पर फ़िल्टरिंग मेरे पास Account
इकाई है जिसमें Section
इकाइयों का संग्रह है। प्रत्येक Section
इकाई का संग्रह Element
इकाइयों (OneToMany एसोसिएशन) का संग्रह है। मेरी समस्या यह है कि किसी सेक्शन के सभी तत्वों को लाने के बजाय, मैं एक सेक्शन और से संबंधित सभी तत्वों को एक विशिष्ट खाते से जोड़ना चाहता हूं। नीचे मेरा डेटाबेस मॉडल है।Doctrine2
इस प्रकार, जब मैं कोई खाता लाने, मैं (इस हिस्से कोई समस्या नहीं है) उसके संबंधित वर्गों के माध्यम से लूप करने में सक्षम होना चाहते हैं, और प्रत्येक अनुभाग के लिए, मैं उसके तत्वों हैं कि के माध्यम से लूप करना चाहते हैं प्राप्त खाते से जुड़े। अभी मेरे पास निम्न कोड है।
$repository = $this->objectManager->getRepository('MyModule\Entity\Account');
$account = $repository->find(1);
foreach ($account->getSections() as $section) {
foreach ($section->getElements() as $element) {
echo $element->getName() . PHP_EOL;
}
}
समस्या यह है कि यह किसी दिए गए खंड से संबंधित सभी तत्वों को प्राप्त करता है, भले ही वे किस खाते से जुड़े हों। एक सेक्शन के तत्व लाने के लिए उत्पन्न एसक्यूएल निम्नानुसार है।
SELECT t0.id AS id1, t0.name AS name2, t0.section_id AS section_id3
FROM mydb.element t0
WHERE t0.section_id = ?
मुझे ऐसा करने की ज़रूरत है जो नीचे की तरह कुछ है (कोई अन्य दृष्टिकोण हो सकता है)। यह महत्वपूर्ण है कि फ़िल्टरिंग एसक्यूएल के साथ की जाती है।
SELECT e.id, e.name, e.section_id
FROM element AS e
INNER JOIN account_element AS ae ON (ae.element_id = e.id)
WHERE ae.account_id = ?
AND e.section_id = ?
मुझे पता है कि मैं एक विधि getElementsBySection($accountId)
या एक कस्टम भंडार में समान लिखने और DQL का उपयोग कर सकते है। यदि मैं ऐसा कर सकता हूं और Section
इकाई पर getElements()
विधि को किसी भी तरह ओवरराइड कर सकता हूं, तो यह सही होगा। अगर मैं एसोसिएशन मैपिंग्स के माध्यम से या कम से कम मौजूदा गेटर विधियों का उपयोग करके ऐसा करने का कोई तरीका होगा तो मैं बहुत पसंद करूंगा। आदर्श रूप से, खाता ऑब्जेक्ट का उपयोग करते समय, मैं उपरोक्त कोड स्निपेट की तरह लूप करने में सक्षम होना चाहता हूं ताकि ऑब्जेक्ट का उपयोग करते समय "खाता बाधा" को सारणीबद्ध किया जा सके। यही है, ऑब्जेक्ट के उपयोगकर्ता को getElementsByAccount()
या Section
ऑब्जेक्ट पर कॉल करने की आवश्यकता नहीं है, क्योंकि यह कम सहज लगता है।
मैंने Criteria
ऑब्जेक्ट में देखा, लेकिन जहां तक मुझे याद है, इसका उपयोग एसोसिएशन पर फ़िल्टर करने के लिए नहीं किया जा सकता है।
तो, इसे पूरा करने का सबसे अच्छा तरीका क्या है? क्या यह Section
इकाई को डीक्यूएल प्रश्नों के उपयोग के माध्यम से तत्वों के साथ "मैन्युअल रूप से" इकट्ठा किए बिना संभव है? मेरा वर्तमान (और छोटा) स्रोत कोड नीचे देखा जा सकता है। आपका अग्रिम रूप से बोहोत धन्यवाद!
/**
* @ORM\Entity
*/
class Account
{
/**
* @var int
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
protected $id;
/**
* @var string
* @ORM\Column(type="string", length=50, nullable=false)
*/
protected $name;
/**
* @var ArrayCollection
* @ORM\ManyToMany(targetEntity="MyModule\Entity\Section")
* @ORM\JoinTable(name="account_section",
* joinColumns={@ORM\JoinColumn(name="account_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="section_id", referencedColumnName="id")}
*)
*/
protected $sections;
public function __construct()
{
$this->sections = new ArrayCollection();
}
// Getters and setters
}
/**
* @ORM\Entity
*/
class Section
{
/**
* @var int
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
protected $id;
/**
* @var string
* @ORM\Column(type="string", length=50, nullable=false)
*/
protected $name;
/**
* @var ArrayCollection
* @ORM\OneToMany(targetEntity="MyModule\Entity\Element", mappedBy="section")
*/
protected $elements;
public function __construct()
{
$this->elements = new ArrayCollection();
}
// Getters and setters
}
/**
* @ORM\Entity
*/
class Element
{
/**
* @var int
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
protected $id;
/**
* @var string
* @ORM\Column(type="string", length=50, nullable=false)
*/
protected $name;
/**
* @var Section
* @ORM\ManyToOne(targetEntity="MyModule\Entity\Section", inversedBy="elements")
* @ORM\JoinColumn(name="section_id", referencedColumnName="id")
*/
protected $section;
/**
* @var \MyModule\Entity\Account
* @ORM\ManyToMany(targetEntity="MyModule\Entity\Account")
* @ORM\JoinTable(name="account_element",
* joinColumns={@ORM\JoinColumn(name="element_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="account_id", referencedColumnName="id")}
*)
*/
protected $account;
// Getters and setters
}
पहला समाधान काम करना चाहिए, लेकिन ऐसा आकर्षक नहीं लगता है क्योंकि फ़िल्टरिंग स्मृति में और एसक्यूएल में किया जाता है यदि मैं सही ढंग से समझता हूं। भंडार दृष्टिकोण के साथ, मैं 'सेक्शन' ऑब्जेक्ट्स मैन्युअल रूप से "संयोजन" करूँगा, है ना? यही है, तत्वों के माध्यम से स्वचालित रूप से प्राप्त किए जाने के बजाय तत्वों को स्वयं स्थापित करना। शायद [इस तरह कुछ] (http://pastebin.com/CWAadsbB)? उस स्थिति में, मैं यह सुनिश्चित करने के लिए इकाई पर एसोसिएशन को भी हटा सकता हूं कि गलत वर्गों को गलती से नहीं लाया जाता है यदि इसका उपयोग करने से पहले ऑब्जेक्ट को इकट्ठा नहीं किया जाता है। अच्छे अंक, वैसे! – Andy0708
पहले समाधान के साथ डीबी परिभाषित संघों के आधार पर केवल इकाइयों को लाएगा। विशिष्ट 'खाता' पर फ़िल्टरिंग केवल PHP में ही की जाएगी। यही कारण है कि मेरा सुझाव है कि आप एक भंडार का उपयोग करें, क्योंकि आप डीबी को केवल उन्हीं तत्वों को प्राप्त कर सकते हैं जिन्हें आप वास्तव में चाहते हैं (इसलिए डीबी फ़िल्टरिंग करता है)। –
मैंने एक उदाहरण क्वेरी के साथ अपना जवाब अपडेट कर दिया है। –