symfony - 如果不存在则添加或检索另一个实体中的实体

标签 symfony doctrine-orm

这是我的问题:我有 2 个名为“Brand”和“Element”的实体。每个元素都与一个独特的品牌相关。

品牌实体

/**
* Brand
*
* @ORM\Entity(repositoryClass="Acme\AcmeBundle\Entity\BrandRepository")
*/

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

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

    /**
     * @ORM\Column(name="model", type="string", length=255, nullable=true)
     */
    private $model;

元素实体

/**
 * Element
 *
 * @ORM\Entity(repositoryClass="Acme\AcmeBundle\Entity\ElementRepository")
 */

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

    /**
     * @ORM\Column(name="serial", type="string", length=255)
     */
    private $serial;

    ... others properties ...

    /**
     * @ORM\ManyToOne(targetEntity="Brand", cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $brand;

我创建了一个集成了品牌表单的元素表单:

// src/Acme/AcmeBundle/Form/ElementType.php

/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('brand', new BrandType())
        ->add('mac')
        ->add('ip')
    ;
}

它工作得很好,但每个新元素都会添加一个新品牌,因此我的表中可以有重复项(例如品牌 2 和 4):

-+--------+----------+-------+
 | ID | name |      model    |
-+--------+----------+-------+
 | 1  | Dell |  Inspiron 14  |
-+--------+----------+-------+
 | 2  | Dell |  Inspiron 15  |
-+--------+----------+-------+
 | 3  | Acer |   Aspire E    |
-+--------+----------+-------+
 | 4  | Dell |  Inspiron 15  |
-+--------+----------+-------+
 | .  |  ..  |      ...      |
-+--------+----------+-------+

添加新元素时,如何检索注册品牌(并将元素与其映射)而不是添加新品牌?

我考虑过在 PrePersist 函数中调用 EntityManager(如果存在“名称+型号”这对,则在 Brand 中搜索,如果存在则返回此对象),但根据其他人的说法,这不是一个好的解决方案。

编辑

这是我使用的解决方案:

// src/Acme/AcmeBundle/Controller/AcmeController.php

public function createAction(Request $request)
{
    $entity = new Element();
    $form = $this->createForm(...);
    $form->handleRequest($request);

    if ($form->isValid()) {

        $brand = $this->getDoctrine()
               ->getRepository('AcmeAcmeBundle:Brand')
               ->findOneBy(array(
                   'name' => $entity->getBrand()->getName(),
                   'model' => $entity->getBrand()->getModel()
                ));
        if($brand)
            $entity->setBrand($brand);

        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();

        // Redirect
    }
}

最佳答案

在持久化任何实体之前,您可以将其触发为:

    $entity = $em->getRepository('Brand')->findOneBy([
        'model' => $model, 
        'name' => $name
    ]);

    if ($entity == null)
    {
        //no brand found. So, persist the new one:
        ...
    }
    else
    {
        $element->setBrand($theNewBrand);
    }

关于symfony - 如果不存在则添加或检索另一个实体中的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19813806/

相关文章:

php - Symfony 表单集合不保存引用

php - Symfony2 : Where place slug and timestamp methods?

php - 使用PHP和mysql大数据导入到多张外键表

php - Symfony2 Lazy Services 何时使用?

php - Symfony PHPUnit 测试(错误 500)

php - 如何立即禁用对被软删除或不再启用的用户的访问?

apache - Symfony .htaccess 为 app_MYNAME.php 添加规则

php - Doctrine GeneratedValue=NONE 不断为 Id 插入 NULL

mysql - Symfony2 空白页

php - 在 "anonymous"用户上存储数据