【问题标题】:Doctrine + Zend Framework 2: Insert array of data in a many to many relationshipDoctrine + Zend Framework 2:以多对多关系插入数据数组
【发布时间】:2016-02-24 19:12:07
【问题描述】:

我有一个使用 Zend Framework2 和 Doctrine2 作为 ORM 的应用程序。 我有一个名为 User 的实体:

namespace Adm\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="user")
 */
class User{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer");
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

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

    /**
     * @ORM\Column(type="string")
     */
    protected $email;

    /**
     * @ORM\Column(type="string")
     */
    protected $password;

    /**
     * @ORM\ManyToMany(targetEntity="Module")
     * @ORM\JoinTable(
     *  name="user_module",
     *  joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *  inverseJoinColumns={@ORM\JoinColumn(name="module_id", referencedColumnName="id")}
     * )
     */
    protected $modules;

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

    /**
     * @return the $id
     */
public function getId() {
    return $this->id;
}

/**
 * @return the $name
 */
public function getName() {
    return $this->name;
}

/**
 * @return the $email
 */
public function getEmail() {
    return $this->email;
}

/**
 * @return the $password
 */
public function getPassword() {
    return $this->password;
}

/**
 * @param field_type $id
 */
public function setId($id) {
    $this->id = $id;
}

/**
 * @param field_type $name
 */
public function setName($name) {
    $this->name = $name;
}

/**
 * @param field_type $email
 */
public function setEmail($email) {
    $this->email = $email;
}

/**
 * @param field_type $password
 */
public function setPassword($password) {
    $this->password = $password;
}

/**
 * Add module
 *
 * @param dm\Entity\Module
 * @return User
 */
public function addModules(Module $modules = null){
    $this->modules[] = $modules;
}

/**
 * Get modules
 *
 * @return \Doctrine\Common\Collections\Collection
 */
public function getModules(){
    return $this->modules;
}

}

看到 modules 属性是一个多对多关系,带有一个名为 user_modules 的表。 我也有实体模块:

namespace Adm\Entity;

use Doctrine\ORM\Mapping as ORM;
class Module{
/**
 * @ORM\Id
 * @ORM\Column(type="integer");
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

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

/**
 * @ORM\Column(type="integer")
 */
private $status;

/**
 * @return the $id
 */
public function getId() {
    return $this->id;
}

/**
 * @return the $name
 */
public function getName() {
    return $this->name;
}

/**
 * @return the $status
 */
public function getStatus() {
    return $this->status;
}

/**
 * @param field_type $id
 */
public function setId($id) {
    $this->id = $id;
}

/**
 * @param field_type $name
 */
public function setName($name) {
    $this->name = $name;
}

/**
 * @param field_type $status
 */
public function setStatus($status) {
    $this->status = $status;
}

}

我收到一个数组变量,其中包含要插入表格的表单中的 Post。正如预期的那样,每个 post 元素在 Entity 中都有它的属性。总之,我有一个 $module 变量,它是一个包含模块 ID 的数组。我的问题是:如何在 user_module 表中插入这些数据? 我的添加功能是这样的:

public function addUser($newUser){
        $user = new User();
        $user->setName($newUser['name']);
        ...
        $this->getEm()->persist($user);
        $this->getEm()->flush();
    }

【问题讨论】:

    标签: php orm doctrine-orm zend-framework2


    【解决方案1】:

    首先,您需要拥有@skrilled 提到的cascade={"persist"}

    然后您需要从数据库中检索模块实体。你提到你在 $module 变量中有 id。

    你需要一个类似这样的 DQL 语句

    $builder = $this->getEntityManager()->createQueryBuilder();
    $builder->select('m')
            ->from('Adm\Entity\Module', 'm')
            ->where('m.id IN (:modules)')
            ->setParameter('modules', $modules);
    $moduleEntities= $builder->getQuery()->getResult(Query::HYDRATE_OBJECT);
    

    在您的用户实体中,您将需要

    public function addModules(Array $moduleEntities)
    {
        foreach ($moduleEntities as $module) {
            if ($module instanceof Module) {
                $this->modules[] = $module;
            }
        }
        return $this;
    }
    

    最后,在您的 addUser 方法中,您需要添加来自上述 DQL 的模块数组

    public function addUser($newUser, $moduleEntities)
    {
        $user = new User();
        $user->setName($newUser['name']);
        ....
        $user->addModules($moduleEntities);
        $this->getEm()->persist($user);
        $this->getEm()->flush();
    }
    

    希望对你有帮助

    【讨论】:

    • 太棒了@Garry,你是救生员。它工作得很好,我只需要替换:$moduleEntities= $builder->getQuery()->getResult(Query::HYDRATE_OBJECT); for $moduleEntities= $builder->getQuery()->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_OBJECT); 感谢您的宝贵时间!
    【解决方案2】:

    您应该阅读有关使用cascade 的信息。这将允许您保存/修改/删除关联的关系以及您希望它如何工作。

    在这种情况下,您需要与persist 的关系,因为您希望在保存用户本身时保存关联的实体。

    @ORM\ManyToMany(targetEntity="Module", cascade={"persist"})

    http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html

    By default, no operations are cascaded.

    存在以下级联选项:

    persist:级联将操作持久化到关联实体。

    remove:级联删除操作到关联实体。

    merge :级联合并操作到关联实体。

    detach :将分离操作级联到关联实体。

    refresh:级联刷新操作到关联实体。

    all:级联对关联实体进行持久化、删除、合并、刷新和分离操作。

    【讨论】:

    • 嗨@skrilled,谢谢你的回答,我不知道。我需要将来自 POST 的值插入一个名为 user_module 的表中(由用户实体中的 $modules 属性引用)你能举个例子来说明如何做到这一点吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    • 2013-08-05
    相关资源
    最近更新 更多