经过大量搜索间接关联后,我才提出this question。我想知道的是与这个问题正好相反,所以我要积累它。给定相同的实体:
class Continent {
/**
* @ORM\Id
* @ORM\Column(type="integer", name="id")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Country", mappedBy="continent")
*/
private $countries;
}
class Country {
/**
* @ORM\Id
* @ORM\Column(type="integer", name="id")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Continent", inversedBy="countries")
* @ORM\JoinColumn(name="continent_id", referencedColumnName="id")
*/
private $continent;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\City", mappedBy="country")
*/
private $cities;
}
class City {
/**
* @ORM\Id
* @ORM\Column(type="integer", name="id")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Country", inversedBy="cities")
* @ORM\JoinColumn(name="country_id", referencedColumnName="id")
*/
private $country;
}
有没有办法拥有一个大陆所有城市的集合,而不必每次都建立一个自定义查询,一个字段与国家集合相同,可能通过注释或动态映射?
我能想到的唯一方法是覆盖存储库中的find...
方法 - 我不确定如何才能实现添加字段 - 然后循环遍历各个国家/地区并添加他们的城市是一个新的集合,或完全使用自定义查询。
答案 0 :(得分:1)
首先评论您的映射。你的映射在这里是错误的:
RuntimeException
不是inversedBy="countries"
,您可能想要一个名为inversedBy="country"
的列,而不是continent_id
continentt_id
此处应/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Continent", inversedBy="countries")
* @ORM\JoinColumn(name="continent_id", referencedColumnName="id")
*/
private $continent;
而不是inversedBy="cities"
:
inversedBy="city"
考虑对您的实体模型使用验证,与教条ORM一起提供的验证工具将帮助您正确理解这些内容。
你可以通过内部加入某个特定大陆的国家来获得这样的结果。
在/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Country", inversedBy="cities")
* @ORM\JoinColumn(name="country_id", referencedColumnName="id")
*/
private $country;
内:
CityRepository
您可以重复使用该查询,只需在每次希望不同大陆的城市时,将大陆的其他值传递给use Doctrine\ORM\Query\Expr\Join;
//...
public function findCitiesByContinent($params){
$queryBuilder = $this->createQueryBuilder('c')
->innerJoin('c.country', 'cc', Join::WITH, 'cc.continent = :continent')
->setParameter('continent', $params['continent']);
$query = $queryBuilder->getQuery();
return $query->getResult();
}
数组。
此代码未经过测试,但我认为它应该可行。如果您在测试时遇到问题,请发表评论。
您还可以添加@Edwin建议的方法,但您必须意识到它会急切地加载所有实体。如果您的表(很多城市和国家/地区)中有大量行,这会导致性能下降。这就是为什么您的存储库中的查询会更好。
或者,您可以使用条件和集合过滤在实体内执行此操作。您可以在文档章节 8.8. Filtering Collections
中阅读有关如何执行此操作的信息在文档中也很好地解释了使用过滤器的优点:
如果尚未从数据库加载集合,则过滤API可以在SQL级别上工作,以便对大型集合进行优化访问。