我正在使用DQL选择一起连接几个表的数据集。
我在下面的工作DQL查询(为代码的粗略大小道歉)。
$qb = $this->_em->createQueryBuilder();
$articles_only = ( Content::TYPE_ARTICLE == $type );
if( $countonly ){
$qb->select('COUNT(DISTINCT d.id)')
->from('Entities\Content', 'd')
->join('d.subcategory', 's')
->leftjoin('d.subcategory_contents', 'c');
}
else{
if( $articles_only ){
//ignore brand(s)
$qb->select('partial d.{id, title, type, rank, about_title, super_short_title, short_title, expiry, slug, status, tile_title, tile_description, category_sticky, exclusive, homepage_sticky, show_on_category, updated, created}, partial s.{id, title, slug, homepage_tag}, r, i');
}
else{
$qb->select('partial d.{id, title, type, rank, about_title, super_short_title, short_title, expiry, slug, status, tile_title, tile_description, category_sticky, exclusive, homepage_sticky, show_on_category, updated, created}, partial s.{id, title, slug, homepage_tag}, b, r, i');
}
$qb->distinct()
->addSelect('(CASE WHEN d.expiry < :today THEN 1 ELSE 0 END) AS HIDDEN expired')
->addSelect('(CASE WHEN r.homepage_rank IS NULL THEN '.$toprank.' ELSE r.homepage_rank END) AS HIDDEN homepage_rank')
->addSelect('(CASE WHEN r.category_rank IS NULL THEN '.$toprank.' ELSE r.category_rank END) AS HIDDEN category_rank')
->addSelect('(CASE WHEN r.subcategory_rank IS NULL THEN '.$toprank.' ELSE r.subcategory_rank END) AS HIDDEN subcategory_rank')
->addSelect('(CASE WHEN r.default_rank IS NULL THEN '.$toprank.' ELSE r.default_rank END) AS HIDDEN default_rank')
->from('Entities\Content', 'd')
->join('d.subcategory', 's')
->leftjoin('d.subcategory_contents', 'c')
->leftjoin('d.content_rank', 'r')
->leftjoin('d.tile_image', 'i');
if( ! $articles_only ){
$qb->leftjoin('d.brand', 'b');
}
$qb->setParameter('today', new \DateTime());
}
//get online content only
$qb->andWhere('d.status = :status')->setParameter('status', Content::STATUS_ONLINE);
if( $type ){
if( is_array( $type ) ) {
$qb->andWhere('d.type IN (:type)')->setParameter('type', $type);
}
else
$qb->andWhere('d.type = :type')->setParameter('type', $type);
}
if( $subcategory ) {
//--- subcategory content ---//
if( is_array($subcategory) ){
$subs_ids = array();
foreach($subcategory as $s)
$subs_ids[] = $s->getId();
$qb->andWhere('s.id IN (:subcategory)')->setParameter('subcategory', $subs_ids);
if( ! $countonly )
$qb->addOrderBy('category_rank', 'ASC');
}else{
$qb->andWhere('s.id = :subcategory OR c.subcategory = :subcategory')->setParameter('subcategory', $subcategory->getId());
if( ! $countonly )
$qb->addOrderBy('subcategory_rank', 'ASC');
}
if( ! $countonly ){
$qb->addOrderBy('expired', 'ASC');
$qb->addOrderBy('d.category_sticky', 'DESC');
}
//--- subcategory content ---//
} else {
//--- homepage content ---//
if( ! $articles_only ){
$qb->andWhere('d.expiry IS NULL OR d.expiry >= :today')->setParameter('today', $today);
}
if( ! $countonly ) {
$qb->addOrderBy('homepage_rank', 'ASC');
$qb->addOrderBy('d.homepage_sticky', 'DESC'); // no subcategory so order by home page sticky
}
//--- homepage content ---//
}
if( ! $countonly ){
$qb->addOrderBy('d.updated', 'DESC');
$qb->setFirstResult($offset);
$qb->setMaxResults($limit);
$query = $qb->getQuery();
if( $enable_cache ){
$query->setResultCacheLifetime(30);
$query->useResultCache(true);
}
}
else{
$query = $qb->getQuery();
if( $enable_cache ){
$query->setResultCacheLifetime(30);
$query->useResultCache(true);
}
return $query->getSingleScalarResult();
}
$results = $query->getResult(AbstractQuery::HYDRATE_OBJECT);
//--- filter by rank ---//
$results = new Collections\ArrayCollection( $results );
在Content和ContentRank实体之间,下面定义了一对一的关系:
/**
* @OneToOne(targetEntity="ContentRank", mappedBy="content", cascade={"persist", "remove"})
*/
protected $content_rank;
在登台时,我重新生成了代理类并创建了所有表。但是无法让dql工作,除非我删除所有对ContentRank的引用(例如r,homepage_rank等)。即使只是添加->leftjoin('d.content_rank', 'r')
,也会导致查询失败,并从Doctrine/ORM/Query/QueryException.php on line 49
抛出QueryException。
登台数据库托管在RDS上。我不明白发生了什么!