Doctrine orm 条令实体存储,通过数组查询多个关系

Doctrine orm 条令实体存储,通过数组查询多个关系,doctrine-orm,symfony,Doctrine Orm,Symfony,我有一个实体,报价,与一个国家/地区实体有很多关系(即报价可以在许多国家/地区提供) 我想查询具有给定数组的国家/地区的所有报价 更好理解的图像: 在这种情况下,它应该只显示报价1和报价2,因为前者有安道尔,后者有意大利 从表格中,我有一个国家实体的数组集合 是否可以使用查询生成器在EntityRepository中执行此操作 例如,这是我如何按payoutMode进行过滤的,payoutMode是一个简单的int值: class OfferRepository extends Entity

我有一个实体,
报价
,与一个
国家/地区
实体有很多关系(即报价可以在许多国家/地区提供)

我想查询具有给定数组的国家/地区的所有报价

更好理解的图像:

在这种情况下,它应该只显示报价1和报价2,因为前者有安道尔,后者有意大利

从表格中,我有一个国家实体的数组集合

是否可以使用查询生成器在EntityRepository中执行此操作


例如,这是我如何按payoutMode进行过滤的,payoutMode是一个简单的int值:

class OfferRepository extends EntityRepository
{
    public function findAllFiltered(array $filter = [])
    {
        $qb = $this->createQueryBuilder('offer');

        // Show only active offers
        $qb->where('offer.status=1');

        if($filter['payoutMode'] ?? null) {
            $qb->andWhere("offer.payoutMode = :payoutMode")->setParameter(':payoutMode', $filter['payoutMode']);
        }

        // TODO add filter by cc, category, tags

        return $qb->getQuery()->execute();
    }
}
此处,
$filter['countries]
包含:

ArrayCollection {#748 ▼
  -elements: array:2 [▼
    0 => Country {#762 ▼
      -cc: "AD"
    }
    1 => Country {#769 ▼
      -cc: "IT"
    }
  ]
}

我想我找到了解决办法:

if(count($filter['countries'] ?? [])) {
    $qb->leftJoin('offer.countries', 'countries')
       ->andWhere("countries IN (:ccs)")->setParameter(':ccs', $filter['countries']);
}

在DQL中,函数中有
,它可以将ID数组或实体数组作为右侧参数。将其用于
连接
条件

由于您已经获得了
Country
实体的
ArrayList
,它可能是这样的:

class OfferRepository extends EntityRepository
{
    public function findAllFiltered(array $filter = [])
    {
        $qb = $this->createQueryBuilder('offer');

        // Show only active offers
        $qb->where('offer.status=1');

        if($filter['payoutMode'] ?? null) {
            $qb->join("offer.payoutMode = :payoutMode")->setParameter(':payoutMode', $filter['countries']);
        }

        if(!empty($filter['payoutMode'])) {
             $qb->join('offer.countries', 'c', Expr\Join::WITH, 'c IN :countries')
                ->setParameter(':countries', $filter['countries']);
        }
        // TODO add filter by cc, category, tags

        return $qb->getQuery()->execute();
    }
}
代码没有经过测试,所以我可能会把DQLJOIN语法搞砸。 我不确定在这种情况下,
'c IN:countries'
语法是否有效。
但一般来说,这就是方法。

我们需要处理筛选表单的代码,以及基于这些筛选进行查询的代码。我添加了存储库代码
class OfferRepository extends EntityRepository
{
    public function findAllFiltered(array $filter = [])
    {
        $qb = $this->createQueryBuilder('offer');

        // Show only active offers
        $qb->where('offer.status=1');

        if($filter['payoutMode'] ?? null) {
            $qb->join("offer.payoutMode = :payoutMode")->setParameter(':payoutMode', $filter['countries']);
        }

        if(!empty($filter['payoutMode'])) {
             $qb->join('offer.countries', 'c', Expr\Join::WITH, 'c IN :countries')
                ->setParameter(':countries', $filter['countries']);
        }
        // TODO add filter by cc, category, tags

        return $qb->getQuery()->execute();
    }
}