查询实体内的集合

时间:2013-01-30 00:36:33

标签: symfony doctrine-orm twig

我目前在产品和与产品相关的多笔交易(总共100万笔交易表)中有一对一的简单关系。

我要做的是循环前十大产品并选择与该产品相关的顶级交易。

在Doctrine 2中实现这一目标的最佳方法是什么?我正在考虑在产品实体中添加一个getTopDeals等方法,然后在我循环遍历每个产品时在twig中调用它:

{% for product in popular_products %}
    {% set deal = product.getTopDeal() %}
    {{ product.title }} - {{ deal.title }}, {{deal.price }}
{% endfor %}

但是,我已经读到,一般来说,将这样的方法添加到模型中是不赞成的,所以我最终知道最好的方法是做什么。

2 个答案:

答案 0 :(得分:2)

在Deals仓库中创建一个方法来接受参数并返回topdeal。在您的控制器中,array_map()您的产品将生成一系列按产品键入的交易。然后将deals数组和products数组一起传递给模板。

编辑:请求样本:

存储库:

public function getTopDealProduct($productid)
{
    $em=$this->getEntityManager();
    $qb = $em->getRepository('Bundle:Deal')->createQueryBuilder('d');
    $qb->join('d.product', 'p');
    $qb->setMaxResults(1);
    $qb->addOrderBy('d.price');
    $query = $qb->getQuery();
    $results = $query->getResult();

    return $results;
}

控制器:

public function s2JUsorAction(Request $request, $id)
{
    $dealrep = $this->em->getRepository('Bundle:Deal');
    $prodrep = $this->em->getRepository('Bundle:Product');
    $products= $prodrep->getProducts();  // Not shown here, write this
    $deals= array_map(function($element) use ($dealrep){
         return $dealrep->getTopDealProduct($element->getId());
    }
    ,$products);


    return $this->render('Bundle:Product:Deal.html.twig', array(
        'products'  => $products
       ,'deals'     => $deals
    ));
}

答案 1 :(得分:1)

最佳做法是“胖型,瘦控制器”。如果模型本身能够进行过滤,例如,选择产品的最高交易的逻辑肯定在模型上占有一席之地。它只需要与之有关系的交易对象。为此,您可以使用Criteria API,例如:

use Doctrine\Common\Collections\Criteria;
class Product {
    private $deals; // many-to-many to Products

    public function getTopDeals() {
        $criteria = Criteria::create()->orderBy(array('price', 'DESC'))->setMaxResults(10);
        return $this->deals->matching($criteria);
    }
}

如果选择逻辑更复杂,并且需要进入实体管理器,那么它更适合放置在EntityRepository上。