Doctrine arrayCollections和关系

时间:2015-05-19 23:58:26

标签: symfony doctrine entity

我对Doctrine很新,所以我希望有人可以帮助我或者将我重定向到好的文档页面。

我正在构建一个包含两个实体的应用程序(我会减少解释):
- 投标
- 文件

对于每个投标,我们可以有一个或多个文件。所以我做了以下几件事。

投标:

<?php

namespace TenderBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="tender")
 */
class Tender
{

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $tender_id;

    /**
     * @ORM\Column(type="array")
     * @ORM\ManyToOne(targetEntity="File", inversedBy="tenders")
     * @ORM\JoinColumn(name="tender_files", referencedColumnName="file_id")
     */
    private $tender_files;
}

档案:

<?php

namespace TenderBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;

/**
 * @ORM\Entity
 * @ORM\Table(name="file")
 */
class File
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $file_id;

    /**
     * @ORM\OneToMany(targetEntity="Tender", mappedBy="tender_files", cascade={"persist", "remove"})
     */
    private $file_tender;
}

第一个问题:这是正确的方法吗? (当然,我已经创建了获取和设置属性的方法,但它们是基本的)。

当我保留每个File对象时,我试图将其添加到我的Tender实例中。但要做到这一点,我需要公开$tender_files并执行此操作:

$tender->tender_files[]

这对我来说不是一个可行的解决方案,因为我需要所有字段都是私有的,并且当我尝试调用它时我想要恢复我的对象:

$this->getDoctrine()->getManager()->getRepository('TenderBundle:Tender')->find($id)->getTenderFiles()->getFileName();

所以,我正在解释并要求找到正确的方法来做我想做的事。我希望我需要的是清楚的,我在这里回答问题或在需要时显示更多代码。

谢谢!

3 个答案:

答案 0 :(得分:0)

你的文件实体中应该有一个类似于此的setter和getter:

public function setTender(\Your\Namespace\Tender $tender)
{
    $this->tender = $tender;

    return $this;
}

public function setTender()
{
    return $this->tender;
}

因此,当您实例化(或创建)文件时,您可以这样:

$file = new File(); // or file fetched from DB, etc.
// here set $file properties or whatever
$tender->setFile($file);
$entityManager->persist($tender);
$entityManager->flush();

然后,您的投标将与您的文件正确关联。

同样,从文件结束,你应该能够:

$file->addTender($tender); 
$entityManager->persist($file);
$entityManager->flush();

您的投标将被添加到您的文件 - &gt;招标集合中。

有关详细信息,documentation非常有用,并且或多或少都有您入门所需的一切。

另外,使用generate:doctrine:entity

手动创建getter和setter

答案 1 :(得分:0)

就像理查德提到的那样,你错过了被宣布为公开的吸气者和制定者。他们可以访问您的私有变量。使用symfony快速完成此操作:

php app/console doctrine:generate:entities

它会生成这样的东西:

public function addTenderFile(\TenderBundle\Entity\File $file)
{
    $this->tender_files[] = $file;

    return $this;
}

/**
 * Remove
 */
public function removeTenderFile(\TenderBundle\Entity\File $file)
{
    $this->tender_files->removeElement($file);
}

/**
 * Get
 */
public function getTenderFiles()
{
     return $this->tender_files;
}

如果您是初学者,看看您的代码如何与自动生成器对齐,这是一个很好的做法。一旦你理解了发生了什么,就让发电机做一些笨拙的工作。

答案 2 :(得分:0)

这是不正确的:

/**
 * @ORM\Column(type="array")
 * @ORM\ManyToOne(targetEntity="File", inversedBy="tenders")
 * @ORM\JoinColumn(name="tender_files", referencedColumnName="file_id")
 */
private $tender_files;

您无法将数组持久保存到数据库中。数据库行是一个实体,它是相应的属性。如果招标可以有很多文件,那么这种关系应该是:

* @ORM\OneToMany

同样适用于File实体。如果许多文件可以有一个招标,那么它的关系应该是:

* @ORM\ManyToOne

对于使用Doctrine的关系映射,从左到右阅读实体,你当前是在左边,而你正在设置为变量的实体在右边。

如果您在招标中从左到右阅读投标可能有“OneToMany”文件。而文件可能有ManyToOne Tender。 Doctrine Association Mapping