【问题标题】:Query Builder inside entity - Doctrine实体内部的查询生成器 - 教义
【发布时间】:2016-01-07 18:39:38
【问题描述】:

我正在寻找一种更好的方法来编写这个函数。 它在 Doctrine Entity Model 中

public function getCompanySubscriptions()
{
    foreach ($this->subscriptions as $key => $value) {
        if ($value->getPlan()->getType() == 'E' && $value->getActive()) {
            return $value;
        }
    }
    return null;
}

$this->subscriptions 是一个多对一的集合,可以有不同的“类型”(但只有一个类型为“E”)。

问题是:如果Company 有太多$subscriptions,则此函数将太慢而无法返回只有一个“E”类型,我在使用 TWIG 构建视图时需要检查它。解决方案是使用QueryBuilder,但我还没有找到直接从实体模型中使用它的方法。

【问题讨论】:

标签: php doctrine-orm entity silex query-builder


【解决方案1】:

不能在您的实体中使用QueryBuilder,但您可以使用原则Criteria 来过滤集合(在SQL 级别)。检查documentation chapter 8.8. Filtering Collections for more details on Criteria

如果集合尚未从数据库加载,过滤 API 可以在 SQL 级别上工作,以优化对大型集合的访问。

例如只获得有效订阅:

$subscriptions = $this->getCompanySubscriptions();

$criteria = Criteria::create()
    ->where(Criteria::expr()->eq("active", true));

$subscriptions = $subscriptions ->matching($criteria);

这样您就可以解决性能问题,因为集合是直接使用Criteria 中的条件从数据库加载的。

你的问题可能是你需要加入Plan,但joining is not possible in a Criteria。因此,如果确实需要加入,那么您应该考虑使用自定义查询,在该查询中使用公司EntityRepository 中的条件进行加入(例如使用QueryBuilder)。

注意。 您问题中的foreach 可以使用the filter method from the ArrayCollection 类重写。过滤器接受一个谓词,所有满足该谓词的元素都将被返回。 另请查看here in the doctrine 2 class documentation 了解更多信息。

你的谓词看起来像:

$predicate = function($subscription){
    $subscription->getPlan()->getType() == 'E' && $subscription->getActive();
}

然后:

return $this->subscriptions->filter($predicate);

【讨论】:

    猜你喜欢
    • 2015-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多