链接自己的查询symfony2存储库

链接自己的查询symfony2存储库,symfony,doctrine-orm,Symfony,Doctrine Orm,我想在我的模型存储库中分解一些代码 一个非常基本的例子 public function getPlayers() { $qb = $this->createQueryBuilder('p') ->innerJoin(...) // whatever the request ->where(...) // I want to factorize this line because a lot of function us

我想在我的模型存储库中分解一些代码

一个非常基本的例子

public function getPlayers()
{  
    $qb = $this->createQueryBuilder('p')
        ->innerJoin(...) // whatever the request
        ->where(...)
        // I want to factorize this line because a lot of function use it 
        ->andWhere('p.active = true'); 
    return (...);
}
所以我创建了一个私有函数

private function getActivePlayer() {
    return $this->andWhere('p.active = true');
}
我想在任何函数中都这样使用它

$qb = $this->createQueryBuilder('p')
            ->innerJoin(...)
            ->where(...)
            ->getActivePlayer()
但我当然有这个错误

Attempted to call method "getActivePlayer" on class "Doctrine\ORM\QueryBuilder"
有可能实现这种因式分解吗?什么是合成税


谢谢

您可以尝试以下方法:

public function getPlayers()
{  
    $qb = $this->createQueryBuilder('p')
        ->innerJoin(...)
        ->where(...);
    $qb = $this->getPlayerType($qb);
}

private function getActivePlayer(QueryBuilder $qb)
{
    return $qb->andWhere('p.active = true');
}
class MyQueryBuilder extends \Doctrine\ORM\QueryBuilder {
    public function getActivePlayer() {
        return $this->andWhere('p.active = true');
    }
}

QueryBuilder
对象的上下文中使用
->
运算符将仅调用
QueryBuilder
类中的方法。您必须定义自己的类来扩展
QueryBuilder
。比如:

public function getPlayers()
{  
    $qb = $this->createQueryBuilder('p')
        ->innerJoin(...)
        ->where(...);
    $qb = $this->getPlayerType($qb);
}

private function getActivePlayer(QueryBuilder $qb)
{
    return $qb->andWhere('p.active = true');
}
class MyQueryBuilder extends \Doctrine\ORM\QueryBuilder {
    public function getActivePlayer() {
        return $this->andWhere('p.active = true');
    }
}
然后实现该生成器,而不是默认的查询生成器:

$qb = new MyQueryBuilder();
$qb->select('p')
    ->from(...)
    ->innerJoin(...)
    ->where(...)
    ->getActivePlayer()
    // ...
请注意,上面的代码只是一个简单的演示,它向您展示了实现您想要做的事情所需的时间长度——在实际操作中,您需要做的还不止这些

最好从特定私有方法中的基本QueryBuilder开始,然后在公共getter中修改它:

private function getPlayerQueryBuilder()
{  
    $qb = $this->createQueryBuilder('p')
        ->innerJoin(...) // whatever the request
        ->where(...)
    return $qb;
}

public function getActivePlayers() {
    $result = $this->getPlayerQueryBuilder()
        ->andWhere('p.active = true')
        ->getQuery()->getResult();
    return $result;
}

public function getAllPlayers() {
    $result = $this->getPlayerQueryBuilder()
        ->getQuery()->getResult();
    return $result;
}

->getPlayerType()
应该是
getActivePlayer()
?尤其是因为你发布的内容实际上不起作用。@Cerad正是我这么说的原因。我的答案是对需要做的基本工作的简化版本,但它比这要复杂得多。我提出了一个更好的替代方案,所以希望这对OP更有效。