【问题标题】:Symfony2 doctrine ManyToMany relationSymfony2 原则多对多关系
【发布时间】:2014-08-09 20:55:10
【问题描述】:

我是 Synfony2 和学说用法的初学者。我创建了如下两个实体:

对于最终用户实体(FOSUserBundle 的扩展):

/**
 * EndUser
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Core\CustomerBundle\Entity\EndUserRepository")
 */
class EndUser extends BaseUser {
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="Core\GeneralBundle\Entity\Discipline", mappedBy="endusers")
     */
    private $discipline;

对于学科实体

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

    /**
     * @ORM\ManyToMany(targetEntity="Core\CustomerBundle\Entity\EndUser", inversedBy="discipline")
     */
    private $endusers;

当我做"php app/console doctrine:schema:update -- force时,

EndUserDisciplinediscipline_enduser 表已创建。

当我通过 phpmyadmin 运行标准 SQL 请求时:

select t0.*
from
discipline t0,
discipline_enduser t2
where 
t2.enduser_id = 1
and 
t2.discipline_id = t0.id

我获得预期结果作为特定用户的纪律列表。

我关心的是如何使用带有 Symfony2 和 Doctrine 的实体来实现相同的功能

【问题讨论】:

    标签: symfony many-to-many dql


    【解决方案1】:

    首先,我建议为您的关系使用更多自然语言名称,例如disciplinesendUsers,因为它是manyToMany 键。此外,您需要为每个方法创建 getset 方法。为实体准备好所有属性后,您应该运行命令到Generate your getters and setters

    //this will generate all entities
    php app/console doctrine:generate:entities BundleNamespace
    

    之后,您可以执行以下操作:

    $endUser->getDisciplines(); //return all disciplines of this user
    $endUser->addDiscipline($someDiscipline); //add another discipline
    $endUser->removeDiscipline($iAmABadDiscipline); //remove this discipline from this user
    array $disciplines = [ ... ];
    $endUser->setDisciplines($disciplines); // set multiple disciplines
    

    同样的逻辑适用于Discipline 实体,当然您应该使用EntityManager 更新它们,您可以在答案here 中阅读更多信息。

    【讨论】:

      【解决方案2】:

      您真正需要做的就是修改您的 EndUser 实体以包含以下内容:

      use Doctrine\Common\Collections\ArrayCollection;
      
      class EndUser extends BaseUser 
      {
          private $discipline;
      
          public function __construct()
          {
              $this->discipline = new ArrayCollection();
          }
      
          public function setDiscipline($discipline)
          {
              $this->discipline = $discipline;
      
              return $this;
          }
      
          public function getDiscipline()
          {
              return $this->discipline;
          }
      }
      

      然后类似地修改 Discipline,用 endUser 代替纪律。

      无需创建中间实体。教义已经想通了。整齐,嗯?!

      【讨论】:

        【解决方案3】:

        为了使事情更加连贯,请将您的班级成员重命名为 $disciplines(它是多对多的,因此其中可能有多个学科)。然后,您需要实体中的 setter 和 getter 来访问学科。

        一种方法是在命令行上执行此操作:

        php app/console doctrine:generate:entities YourBundle:EndUser
        

        这会将所需的方法添加到您的类中。未修改版本的类文件备份在 EndUser.php~ 中,以防任何内容被覆盖。

        做完之后,就可以直接调用getter来获取学科了:

        $disciplines = $anEndUser->getDisciplines();
        

        例如在控制器方法中:

        public function someAction()
        {
            $anEndUser = $this
                ->getDoctrine()
                ->getManager()
                ->getRepository('YourBundle:EndUser')
                ->find(1)
            ;
            $disciplines = $anEndUser->getDisciplines();
        }
        

        【讨论】:

          猜你喜欢
          • 2015-04-05
          • 1970-01-01
          • 1970-01-01
          • 2014-05-18
          • 2014-09-14
          • 1970-01-01
          • 2022-01-22
          • 1970-01-01
          相关资源
          最近更新 更多