删除原则 2 中多对多关系中的相关实体的行


Delete row from related entity in many to many relationship in Doctrine2

我有这个实体:

class FabricanteProductoSolicitud
{
    use IdentifierAutogeneratedEntityTrait;
    /**
     * @ORM'ManyToOne(targetEntity="'AppBundle'Entity'FabricanteDistribuidor")
     * @ORM'JoinColumn(name="fabricante_distribuidor_id", referencedColumnName="id")
     */
    protected $fabricante_distribuidor;
    /**
     * @ORM'ManyToOne(targetEntity="'AppBundle'Entity'ProductoSolicitud")
     * @ORM'JoinColumn(name="producto_solicitud_id", referencedColumnName="id")
     */
    protected $producto_solicitud;
    /**
     * @ORM'ManyToMany(targetEntity="'AppBundle'Entity'Pais", inversedBy="fabricanteProductoSolicitudPais", cascade={"persist"})
     * @ORM'JoinTable(name="nomencladores.pais_fabricante_producto_solicitud", schema="nomencladores",
     *      joinColumns={@ORM'JoinColumn(name="fabricante_producto_solicitud_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM'JoinColumn(name="pais_id", referencedColumnName="id")}
     * )
     */
    protected $paisesFabricanteProductoSolicitudPais;
    /**
     * @ORM'ManyToMany(targetEntity="'AppBundle'Entity'ModeloMarcaProducto", inversedBy="modeloMarcaProducto", cascade={"persist"})
     * @ORM'JoinTable(name="negocio.fabricante_modelo_marca_producto", schema="negocio",
     *      joinColumns={@ORM'JoinColumn(name="fabricante_producto_solicitud_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM'JoinColumn(name="modelo_marca_producto_id", referencedColumnName="id")}
     * )
     */
    protected $modeloMarcaProducto;
    public function __construct()
    {
        $this->paisesFabricanteProductoSolicitudPais = new ArrayCollection();
        $this->modeloMarcaProducto = new ArrayCollection();
    }
    public function addModeloMarcaProducto(ModeloMarcaProducto $modeloMarcaProducto)
    {
        $this->modeloMarcaProducto[] = $modeloMarcaProducto;
    }
    public function removeModeloMarcaProducto(ModeloMarcaProducto $modeloMarcaProducto)
    {
        $this->modeloMarcaProducto->removeElement($modeloMarcaProducto);
        return $this;
    }    
    public function getModeloMarcaProducto()
    {
        return $this->modeloMarcaProducto;
    }
}

通过 Ajax,我向处理多个值的方法发出了请求:

foreach ($request->request->get('items') as $item) {
    // delete row if it can be deleted 
}

在上面的代码中,$item['value']保存negocio.fabricante_modelo_marca_producto.fabricante_producto_solicitud_id值,这个想法是通过给出fabricante_producto_solicitud_id从相关表(fabricante_modelo_marca_producto)中删除每一行,有什么可以给我一些帮助吗?

编辑:找到最佳方法

为了找到最佳方法,我编写了这段代码:

foreach ($request->request->get( 'items' ) as $item) {
    $relacion = $this->get( 'database_connection' )->fetchColumn(
        'SELECT COUNT(fabricante_producto_solicitud_id) AS cnt FROM negocio.fabricante_modelo_marca_producto WHERE fabricante_producto_solicitud_id = ?',
        array( $item['value'] )
    );
    if ($relacion === 0) {
        $entFabricanteProductoSolicitud = $em->getRepository(
            "AppBundle:FabricanteProductoSolicitud"
        )->find( $item['value'] );
        try {
            $em->remove( $entFabricanteProductoSolicitud );
            $em->flush();
            array_push( $itemsRemoved, $item['value'] );
            $response['success'] = true;
            $status              = 200;
        } catch ( 'Exception $e ) {
            $status = 400;
            dump( $e->getMessage() );
            return new JsonResponse( $response, $status ?: 200 );
        }
    }
    $response['itemsRemoved'] = $itemsRemoved;
}

}

也许它有一些问题,因为我还没有写并且它没有经过测试,但通过这种方式,我可以知道哪个项目被删除了,哪些没有,对吧?这是正确的方法吗?

我会这样做:

首先,使用联接检索所有$fabricanteProductoSolicitud,以便在一个查询中获取其$modeloMarcaProducto

其次,检查结果并清除持久化$fabricanteProductoSolicitud $modeloMarcaProducto(这不会转换为对数据库的访问,只是将实体标记为已删除的 Doctrine)。

第三,使用flush将更改发送到数据库:

        $em = $this->getDoctrine()->getEntityManager();
        $qb = $em->createQueryBuilder();
        $ret = $qb
                ->select("u")
                ->from('MyBundle:FabricanteProductoSolicitud', 'u')
                ->join("u.modeloMarcaProducto","f")
                ->add('where', $qb->expr()->in('u.id', ':ids'))
                ->setParameter('ids',$request->request->get('items'))
                ->getQuery()
                ->getResult();
        foreach($ret as $fabricantePS) {
            $fabricantePS->getModeloMarcaProducto()->clear();
            $em->persist($fabricantePS);
        }
        $em->flush();

这应该从联接表中删除所有实体,并在fabricante_producto_solicitud_id $request->request->get('items')

你可以

这样做,

在控制器 ajax 操作中:

 foreach ($request->request->get('items') as $item) {
    $em = $this->getDoctrine()->getManager();
    $fabricanteProductoSolicitud = $em->getRepository('YourBundle:FabricanteProductoSolicitud')->find($item['value']);
    $modeloMarcaProductos = $fabricanteProductoSolicitud->getModeloMarcaProducto();
        foreach($modeloMarcaProductos as $modeloMarcaProducto)
        {
            //echo $modeloMarcaProducto->getId();
            $fabricanteProductoSolicitud->removeModeloMarcaProducto($modeloMarcaProducto);
            $em->flush();
        }
    }
 }
 // return response; or exit;

希望这对您有所帮助。

我想知道其他用户的更好答案。