教义一对多关系

Posted

技术标签:

【中文标题】教义一对多关系【英文标题】:Doctrine One to Many relationship 【发布时间】:2015-05-24 04:48:23 【问题描述】:

我对一对多关系的教义感到困惑。

问题 1:

如果我错了,请纠正我。我假设当我尝试

$em = $this->getDoctrine()->getManager();
$product_repo = $em->getRepository('MyBundle:Product');
$products = $product_repo->findAll();
dump($products);

我将看到附加到 $features 变量的相关功能,因此当我使用 $products->getFeatures() 时,我将拥有数组形式的 Feature 对象。但是从转储调试中我没有看到任何附加的东西,而是得到了这个:

另一方面,我也这样做

$em = $this->getDoctrine()->getManager();
$feature_repo = $em->getRepository('MyBundle:Features');
$features = $product_repo->findAll();
dump($features);

这次我可以看到 Product 对象附加到 $product 变量。

我的问题是,为什么我不能从变量 $features 中获取数据有什么问题吗?否则学说默认不会加载相关数据。

问题 2:

如果我们假设数据能够加载到功能 $variable 中,我是否可以过滤数据(例如 where feature.name = 'fly')而不是加载所有相关功能。

================================================ =============================

我的演示实体

<?php
use Doctrine\Common\Collections\ArrayCollection;

/** @Entity **/
class Product

    // ...
    /**
     * @OneToMany(targetEntity="Feature", mappedBy="product")
     **/
    private $features;
    // ...

    public function __construct() 
        $this->features = new ArrayCollection();
    


/** @Entity **/
class Feature

    // ...
    /**
     * @ManyToOne(targetEntity="Product", inversedBy="features")
     * @JoinColumn(name="product_id", referencedColumnName="id")
     **/
    private $product;
    // ...

产品表(在数据库中): id、描述、名称

特征表(在数据库中): id、描述、名称、table_id

【问题讨论】:

【参考方案1】:

假设你的转储函数是 symfony/var-dumper 而不是自定义函数

问题 1

是的,转储函数默认不显示嵌套集合,这与性能有关。这不是教义相关的问题。您的数据已加载到此处。

您可以玩转 var-dumper 的高级用法,例如脚轮 (http://symfony.com/doc/current/components/var_dumper/advanced)

问题 2

你有不同的方法来解决你的问题:

在 Controller 中:在 Product 中创建您的自定义方法

标准更好的解决方案

Product::getFeaturesByName($name='fly')
  $criteria = Criteria::create();
  $criteria->where(Criteria::expr()->eq('name', $name));
  return $this->features->matching($criteria);

过滤器

Product::getFeaturesByName($name='fly')

  return $this -> features ->filter(
      function($entry) use ($name) 
         return $entry->getName() == $name;
      
  );

);

在 Twig 模板中:循环过滤

% for product in products % # start browse products #
  % for feature in product.features if feature.name='ok' %# start browse features #

  % endfor %# end browse features #
% endfor %# end browse products #

希望对你有帮助

问候

【讨论】:

非常感谢你,我的日子也一样。我还有关于问题 2 的其他问题,您在此处列出的所有方法是否都会加载我输入的特定值,还是仍会从 db 加载所有值并对程序进行过滤? By Criteria 是最优化的解决方案:如果集合不是从 db 加载的,它将仅选择符合条件的实体。通过过滤器或树枝解决方案加载数据库中的所有数据并在“程序”上进行过滤。

以上是关于教义一对多关系的主要内容,如果未能解决你的问题,请参考以下文章

关于与查询构建器的“一对多”关系的教义内连接

需要帮助了解一对多的教义

Zend 2 - 教义如何为三个实体插入一对多?

教义:加入一对一的关系

Laravel 一对多关系和一对一关系

数据库一对一对多多对多关系