原则 + Zend 框架 2:在多对多关系中插入数据数组


Doctrine + Zend Framework 2: Insert array of data in a many to many relationship

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

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;
}
}

请参阅模块属性是具有名为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 元素在实体中都有其属性。我一起有一个$module变量,它是一个包含模块 id 的数组。我的问题是:如何在user_module表中插入此数据?我的添加函数是这样的:

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

您需要@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();
}

我希望这有帮助

您应该阅读有关使用 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.

存在以下级联选项:

持久

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

删除

:级联删除关联实体的操作。

合并

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

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

刷新

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

all :级联将操作保留、删除、合并、刷新和分离到关联的实体。