简体   繁体   English

原则:一次获取所有相关实体的更有效方法?

[英]Doctrine: a more efficient way to fetch all related entities in one swoop?

So in my system, I have products, which have option_names, which have option_values. 因此,在我的系统中,我有一些产品,这些产品具有option_names,这些产品具有option_values。 The only way of fetching those that I could get to work is this one: 获取那些我可以工作的唯一方法是:

public function productAction($id)
{
    $orm = $this
        ->getDoctrine();

    $product = $orm
        ->getRepository('AppBundle:Catalogue\Product')
        ->find($id);

    $options = $orm
        ->getRepository('AppBundle:Catalogue\OptionName')
        ->findByProduct($product);   

    $values = [];

    foreach($options as $option)
    {
        $values[$option->getId()] = $orm
            ->getRepository('AppBundle:Catalogue\OptionValue')
            ->findByOptionName($option);
    }

    return $this->render(
        'catalogue/product.html.twig',
        array(
            'product' => $product,
            'options' => $options,
            'values' => $values
        )
    );
}

That doesn't look very efficient to me. 在我看来,这并不是很有效。 Using normal SQL, I would just do a table join, but I can't do that here. 使用普通的SQL,我只会做一个表联接,但是我不能在这里做。

I tried to make my own repository and use the join() feature of DQL, but it inexplicably gives me an error about the 'id' index not existing (my ManyToOne, OneToMany & Join annotations are fine, I checked, double-checked and triple-checked). 我试图建立自己的存储库并使用DQL的join()功能,但莫名其妙地给我一个关于'id'索引不存在的错误(我的ManyToOne,OneToMany和Join注释很好,我检查了一下,再检查了一下,三重检查)。 None of the solutions I googled were the one for me, so I essentially ragequit from that whole idea. 我搜索过的所有解决方案都不是适合我的解决方案,因此从本质上讲,我对整个想法并不满意。

Okay, I think these are some root issues 好吧,我认为这是一些根本问题

I've got an association defined through annotations like so: 我有一个通过注释定义的关联,如下所示:

In Product: 产品中:

namespace AppBundle\Entity\Catalogue;

use Doctrine\ORM\Mapping as ORM;
use Repository\Product;

/**
 * Represents a Product (chair, bed, etc) as fetched from the database 'product' table. 
 *
 * @ORM\Entity(repositoryClass="AppBundle\Entity\Catalogue\ProductRepository")
 * @ORM\Table(name="product")
 */
class Product
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\OneToMany(targetEntity="OptionName", mappedBy="product")
     */
    private $id;

In OptionName: 在OptionName中:

namespace AppBundle\Entity\Catalogue;

use Doctrine\ORM\Mapping as ORM;

/**
 * Represents a Product's OptionName (finish, handle, etc). Refer to product documentation on the database design.
 *
 * @ORM\Entity
 * @ORM\Table(name="option_name")
 */
class OptionName
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\OneToMany(targetEntity="OptionValue", mappedBy="optionName")
     */
    private $id;

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

And in OptionValue: 在OptionValue中:

<?php

namespace AppBundle\Entity\Catalogue;

use Doctrine\ORM\Mapping as ORM;

/**
*  Represents an OptionValue (e.g. blue metal handle). Refer to product documentation on the database design.
*  
*  @ORM\Entity
*  @ORM\Table(name="option_value")
*/

class OptionValue
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * The ID of the OptionName
     *
     * @ORM\ManyToOne(targetEntity="OptionName", inversedBy="id")
     * @ORM\JoinColumn(name="option_name", referencedColumnName="id")
     */
    private $optionName;

Why do I get these errors: 为什么会出现这些错误:

The association AppBundle\Entity\Catalogue\OptionName#product refers to the inverse side field AppBundle\Entity\Catalogue\Product#id which is not defined as association.
The association AppBundle\Entity\Catalogue\OptionName#product refers to the inverse side field AppBundle\Entity\Catalogue\Product#id which does not exist.

The association AppBundle\Entity\Catalogue\OptionValue#optionName refers to the inverse side field AppBundle\Entity\Catalogue\OptionName#id which is not defined as association.
The association AppBundle\Entity\Catalogue\OptionValue#optionName refers to the inverse side field AppBundle\Entity\Catalogue\OptionName#id which does not exist.

claiming that the fields do not exist, when clearly, they do? 声称这些字段不存在,如果清楚,它们会存在吗?

If I correctly understand your class relationships: 如果我正确理解您的班级关系:

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Product
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToMany(targetEntity="Option")
     */
    private $options;

    public function __construct()
    {
        $this->options = new ArrayCollection();
    }

    public function getOptions()
    {
        return $this->options;
    }
}

Option: 选项:

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Option
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string")
     */
    private $name;
}

Generated sql: 生成的sql:

CREATE TABLE option (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT 
NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE product (id INT AUTO_INCREMENT NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE product_option (product_id INT NOT NULL, option_id INT NOT NULL, INDEX IDX_6F9B0F6A4584665A (product_id), INDEX IDX_6F9B0F6AA7C41D6F (option_id), PRIMARY KEY(product_id, option_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

Usage: 用法:

public function productAction($id)
{
    $orm = $this
        ->getDoctrine();

    $product = $orm
        ->getRepository('AppBundle:Catalogue\Product')
        ->find($id);

    return $this->render(
        'catalogue/product.html.twig',
        array(
            'product' => $product
        )
    );
}

Template: 模板:

<ul>
    {% for option in product.options %}
        <li>{{ option.name }}</li>
    {% endfor %}
</ul>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM