【问题标题】:Proper way to check if many-to-many relation exists - Symfony2/Doctrine检查是否存在多对多关系的正确方法 - Symfony2/Doctrine
【发布时间】:2013-01-08 07:40:30
【问题描述】:

假设我有两个实体 User 和 Product,通过与 Doctrine 的多对多关系相关。

我想知道为我的用户实体处理返回 true 的 $user->hasProduct($product) 方法的最佳方法是存在关系,否则返回 false。

我目前正在这样做:

public function hasProduct($id)
{
    foreach($this->getProducts() as $product) {
        if($product->getId() == $id) {
            return true;
        }
    }

    return false;
}

但我不确定这是不是最好的方法,尤其是在循环中有很多关系的情况下。

如果有人有更好的东西,请告诉我:)

【问题讨论】:

    标签: symfony doctrine


    【解决方案1】:

    你的函数getProducts 给你一个ArrayCollection

    做事

    if($user->getProducts()->contains($product)) //the real product object not the id
           //your stuff
    

    编辑:

    对于树枝模板:

    {% if product in user.products %}
        //your stuff
    {% endif %}
    

    【讨论】:

    • 听起来不错!我会用那个。有没有办法在树枝模板中执行此操作?
    • 如果我想检查例如如果具有给定名称的产品退出?
    • 您必须手动循环浏览产品或使用自定义 DQL 查询
    • 注意:在使用 contains() 之前,您实际上不需要获取对象。惰性引用就足够了,您可以使用$product = $em->getReference('MyBundle:MyProduct', $id) 获得它。这不会导致数据库查询。
    • @MilesM。那将是 {% if product not in user.products %} //your stuff {% endif %}
    【解决方案2】:

    我在同样的问题上苦苦挣扎,遇到了this 博客文章,它通过使用 Doctrine Filters 解决了这个问题。

    如果我正确理解您的问题并且您有三个表(user、user_product 和 product),您应该能够像这样重写您的 hasProduct($id) 函数:

    use Doctrine\Common\Collections\Criteria;
    
    public function hasProduct(int $productId): bool {
    
      $criteria = Criteria::create();
      $criteria->where(Criteria::expr()->eq('id', $productId));
    
      if(count($this->products->matching($criteria)) > 0) {
        return true;
      }
    
      return false;
    }
    

    运行此代码时,Doctrine 不会加载链接到用户的所有产品。它实际上只查询交叉引用表(user_product)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-20
      • 2014-09-14
      • 1970-01-01
      • 2014-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多