首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >symfony理论many_to_many与3个实体

symfony理论many_to_many与3个实体
EN

Stack Overflow用户
提问于 2017-06-14 17:11:01
回答 3查看 873关注 0票数 2

我有3个实体:

第一个:

代码语言:javascript
复制
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * ProactiveSubject
 *
 * @ORM\Table(name="ProactiveSubject")
 * @ORM\Entity
 */
class ProactiveSubject
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;

/**
 * @ORM\ManyToMany(targetEntity="ProactiveCheck", inversedBy="p_subjects")
 * @ORM\JoinTable(name="subject_check_operator")
 */
private $checks;

public function __construct() {
    $this->checks = new \Doctrine\Common\Collections\ArrayCollection();
  }
}

第二个:

代码语言:javascript
复制
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * ProactiveCheck
 *
 * @ORM\Table(name="ProactiveCheck")
 * @ORM\Entity
 */
class ProactiveCheck
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;

/**
 * @ORM\ManyToMany(targetEntity="ProactiveSubject", mappedBy="ProactiveChecks")
 */
private $p_subjects;

public function __construct() {
    $this->p_subjects = new \Doctrine\Common\Collections\ArrayCollection();
  }

}

第三个:

代码语言:javascript
复制
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * ProactiveOperator
 *
 * @ORM\Table(name="ProactiveOperator")
 * @ORM\Entity
 */
 class ProactiveOperator
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;
/**
 * @ORM\ManyToMany(targetEntity="ProactiveSubject", inversedBy="p_subjects")
 *
 */
private $p_operator;

public function __construct() {
    $this->p_operator = new \Doctrine\Common\Collections\ArrayCollection();
  }

}

简而言之,一个主题可能有很多检查,这些检查可能有很多运算符,所以应该是这样的:

代码语言:javascript
复制
subject1 ==> check EQUALITY ==> operator =
subject1 ==> check GREATER  ==> operator >
subject2 ==> check AMOUNT ==> operator = or operator > or operator < etc... depending on user input

我需要在我的数据库中建立一个类似many_tomany_tomany的连接,这样3个实体就应该通过1个连接表连接起来。问题是,当我运行doctrine:schema:update --force时,它只连接了两个实体(operatorsubject),但没有连接Check实体。有什么想法可以解决这个问题,并用这些实体创建一个表subject_check_operator吗?任何想法都是受欢迎的。谢谢。

EN

回答 3

Stack Overflow用户

发布于 2017-06-14 20:07:27

你在这里有几个问题,对我来说,不清楚你的例子中的EQUALITYGREATER等是什么意思,但如果是这样:

简而言之,1个subject可能有很多检查,这些检查可能有很多运算符,所以应该是这样的:

问题是,当我运行entity :schema:update --force时,它只连接了两个实体(操作符和主题),但没有连接检查实体。

您的主要问题在这里,而不是您需要修复您的关系映射,它包含几个错误。

您需要决定多对多关系是bidirectional还是unidirectional。对于双向关系,请特别注意documentation about owning and inversing sides of a relation

由于您已经包含了mappedByinversedBy设置,因此我假设您的目标是双向关系。使用双向关系时,可以在注释中指定mappedByinversedBy设置的属性名称,而不是类名等。

ProactiveCheck

对于与subject的关系,mappedBy="ProactiveChecks"应为mappedBy="checks"。并且您完全忽略了与运算符的关系

代码语言:javascript
复制
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * ProactiveCheck
 *
 * @ORM\Table(name="ProactiveCheck")
 * @ORM\Entity
 */
class ProactiveCheck
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @ORM\ManyToMany(targetEntity="ProactiveSubject", mappedBy="checks")
     */
    private $p_subjects;

    /**
     * @ORM\ManyToMany(targetEntity="ProactiveOperator", inversedBy="checks")
     */
    private $operators;

    public function __construct() {
        $this->p_subjects = new \Doctrine\Common\Collections\ArrayCollection();
      }

}

ProactiveOperator

如果许多检查应该有许多运算符,则该类映射错误。您正在创建与ProactiveSubject的关系,但与ProactiveCheck实体没有关系。这就是为什么在更新数据库模式时它不是connecting

它应该看起来像这样:

代码语言:javascript
复制
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

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

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;
    /**
     * @ORM\ManyToMany(targetEntity="ProactiveChecks", mappedBy="operators")
     *
     */
    private $p_operator;

    public function __construct() {
        $this->p_operator = new \Doctrine\Common\Collections\ArrayCollection();
      }
}

顺便说一句,您可以使用以下命令轻松地检查映射的有效性:bin/console doctrine:schema:validate

票数 1
EN

Stack Overflow用户

发布于 2017-06-14 17:22:33

也许你可以创建一个实体,它将拥有你想要的3个关系(等同于理论生成的链接表,但是是自定义的)

票数 0
EN

Stack Overflow用户

发布于 2017-06-14 20:00:49

所以你想做一个Entity-(many-to-many)-Entity-(many-to-many)-Entity。这与单一的多对多没有什么不同。你在路上走得很好,但是在你的第三个实体中,你有点链接到第一个实体。

你想要的东西(伪)是这样的:

代码语言:javascript
复制
e1:
    many-to-many: e2

e2:
    many-to-many: e1
    many-to-many: e3

e3:
    many-to-many: e2

您当前所做的是将e3的反面指向e1的反面(e2 > e1属性),因此只需在e2中创建另一个具有多对多属性的属性,指向e3。

只要记住,如果您想要访问每个关系,就需要在类中有一个属性。

但是,这将创建两个连接表。考虑到目前的情况,这是可以接受的。还有另一种方式,e2本质上是带有一些额外字段的连接表。然后你就有了不同的情况,为此,我会向你推荐Doctrine2: Best way to handle many-to-many with extra columns in reference table

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44540362

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档