【问题标题】:Doctrine2 entities relation extra fieldsDoctrine2 实体关系额外字段
【发布时间】:2013-09-19 07:54:21
【问题描述】:

我有以下数据库结构。

Pge\IncidenciasBundle\Entity\Cliente:
    type: entity
    table: cliente
    repositoryClass: Pge\IncidenciasBundle\Entity\ClienteRepository
    id:
      id:
        type: integer
        generator:
          strategy: IDENTITY
    fields:
        nombre:
            type: string
            length: 250
            fixed: false
            nullable: true   
    manyToMany:
        servicios:
            targetEntity: Servicio
            cascade: [persist]
    lifecycleCallbacks: {  }
Pge\IncidenciasBundle\Entity\Servicio:
    type: entity
    table: servicio
    id:
      id:
        type: integer
        generator:
          strategy: IDENTITY
    fields:
        nombre:
            type: string
            length: 250
            fixed: false
            nullable: true
    lifecycleCallbacks: {  }

现在,有一个名为cliente_servicio 的数据库表,用于保存这两个实体之间的关系,例如一些数据:

cliente_id  servicio_id
1           1
1           4
1           8
2           1
3           3
3           7

表单现在完全可以管理这种关系。但是现在,我需要另一个函数。

我需要创建一个新的表单/结构/无论您告诉我如何为每行设置两个额外字段:statuscommentdate 所以最终的数据库输出将是这样的:

cliente_id  servicio_id date        status  comment
1           1           2013-09-19  ok      null
1           4           2013-09-19  ko      Needs to clear
1           8           2013-09-19  ok      null
2           1           2013-09-19  ko      Packets lost (fix firewall)
3           3           2013-09-19  ko      Out of service (see ticket T9388)
3           7           2013-09-19  ok      null

重点是调用路由localhost/whatever/{id}/{date},其中{id}cliente_id(如果需要,可以是客户端名称cliente实体的字段nombre)并且{date}是日期,在此页面索引上,它将显示所选cliente_id 的给定日期的记录数据(我想创建但我不知道如何创建的数据)。

new 操作上,表单将为分配给{id} (cliente_id) 的每个servicio_id 显示estadocommentdate 字段

如果你知道 Symfony2,我认为这很容易,但我完全迷失了......使用简单的 PHP(无框架)我设法处理了这种情况并且它正在工作,但我不知道 Symfony2 如何.

附加信息:

处理manyToMany关系的表cliente_servicio没有映射到Symfony2上,因为它是用doctrine:schema:update --force自动生成的,它不能被映射,因为它缺少id主键(它只有cliente_idservicio_id)

更新

好的,做Doctrine2: Best way to handle many-to-many with extra columns in reference table 所以现在我与clienteservicio 的中间实体有m:1 和1:m 关系,称为clienteservicio

  • 我发现我无法从clienteform 将servicio 分配给cliente

  • 既不是来自servicio 形式。

  • 我可以来自 ClienteServicio 新创建的实体,即“中间”实体。 但是,我不能像以前那样为一个cliente 选择多个servicio

另外,重点是在一个单一的表单中,X 行带有 estadocomentariodate 字段,其中 X = 分配给给定 clienteservicio 的数量

<?php

namespace Pge\IncidenciasBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Cliente
 *
 * @ORM\Table(name="cliente")
 * @ORM\Entity(repositoryClass="Pge\IncidenciasBundle\Entity\ClienteRepository")
 */
class Cliente
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="nombre", type="string", length=250, nullable=true)
     */
    private $nombre;

    /**
     * @var \Doctrine\Common\Collections\Collection
     * @ORM\OneToMany(targetEntity="ClienteServicio", mappedBy="cliente")
     */
    private $servicio;

    public function __toString()
    {
        return $this->nombre;
    }
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->servicio = new \Doctrine\Common\Collections\ArrayCollection();
    }

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

    /**
     * Set nombre
     *
     * @param string $nombre
     * @return Cliente
     */
    public function setNombre($nombre)
    {
        $this->nombre = $nombre;

        return $this;
    }

    /**
     * Get nombre
     *
     * @return string 
     */
    public function getNombre()
    {
        return $this->nombre;
    }

    /**
     * Add servicio
     *
     * @param \Pge\IncidenciasBundle\Entity\ClienteServicio $servicio
     * @return Cliente
     */
    public function addServicio(\Pge\IncidenciasBundle\Entity\ClienteServicio $servicio)
    {
        $this->servicio[] = $servicio;

        return $this;
    }

    /**
     * Remove servicio
     *
     * @param \Pge\IncidenciasBundle\Entity\ClienteServicio $servicio
     */
    public function removeServicio(\Pge\IncidenciasBundle\Entity\ClienteServicio $servicio)
    {
        $this->servicio->removeElement($servicio);
    }

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

<?php

namespace Pge\IncidenciasBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

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

    /**
     * @var string
     *
     * @ORM\Column(name="nombre", type="string", length=250, nullable=true)
     */
    private $nombre;

    /*
     * 
     * @ORM\OneToMany(targetEntity="ClienteServicio", mappedBy="servicio")
     */
    private $cliente;

    public function __toString()
    {
        return $this->nombre;
    }

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

    /**
     * Set nombre
     *
     * @param string $nombre
     * @return Servicio
     */
    public function setNombre($nombre)
    {
        $this->nombre = $nombre;

        return $this;
    }

    /**
     * Get nombre
     *
     * @return string 
     */
    public function getNombre()
    {
        return $this->nombre;
    }
}

<?php

namespace Pge\IncidenciasBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

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

    /**
     * @var integer
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @var string
     *
     * @ORM\Column(name="estado", type="string", length=255, nullable=false)
     */
    private $estado;

    /**
     * @var string
     *
     * @ORM\Column(name="comentario", type="string", length=255, nullable=false)
     */
    private $comentario;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="fecha", type="date", nullable=false)
     */
    private $fecha;

    /**
     * @var \Pge\IncidenciasBundle\Entity\Servicio
     *
     * @ORM\ManyToOne(targetEntity="Servicio", inversedBy="cliente")
     */
    private $servicio;

    /**
     * @var \Pge\IncidenciasBundle\Entity\Id
     *
     * @ORM\ManyToOne(targetEntity="Cliente", inversedBy="servicio")
     */
     private $cliente;

    /**
     * Set id
     *
     * @param integer $id
     * @return ClienteServicio
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

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

    /**
     * Set estado
     *
     * @param string $estado
     * @return ClienteServicio
     */
    public function setEstado($estado)
    {
        $this->estado = $estado;

        return $this;
    }

    /**
     * Get estado
     *
     * @return string 
     */
    public function getEstado()
    {
        return $this->estado;
    }

    /**
     * Set comentario
     *
     * @param string $comentario
     * @return ClienteServicio
     */
    public function setComentario($comentario)
    {
        $this->comentario = $comentario;

        return $this;
    }

    /**
     * Get comentario
     *
     * @return string 
     */
    public function getComentario()
    {
        return $this->comentario;
    }

    /**
     * Set fecha
     *
     * @param \DateTime $fecha
     * @return ClienteServicio
     */
    public function setFecha($fecha)
    {
        $this->fecha = $fecha;

        return $this;
    }

    /**
     * Get fecha
     *
     * @return \DateTime 
     */
    public function getFecha()
    {
        return $this->fecha;
    }

    /**
     * Set servicio
     *
     * @param \Pge\IncidenciasBundle\Entity\Servicio $servicio
     * @return ClienteServicio
     */
    public function setServicio(\Pge\IncidenciasBundle\Entity\Servicio $servicio = null)
    {
        $this->servicio = $servicio;

        return $this;
    }

    /**
     * Get servicio
     *
     * @return \Pge\IncidenciasBundle\Entity\Servicio 
     */
    public function getServicio()
    {
        return $this->servicio;
    }

    /**
     * Set cliente
     *
     * @param \Pge\IncidenciasBundle\Entity\Cliente $cliente
     * @return ClienteServicio
     */
    public function setCliente(\Pge\IncidenciasBundle\Entity\Cliente $cliente = null)
    {
        $this->cliente = $cliente;

        return $this;
    }

    /**
     * Get cliente
     *
     * @return \Pge\IncidenciasBundle\Entity\Cliente 
     */
    public function getCliente()
    {
        return $this->cliente;
    }
}

正如我所说,重点是将serviciocliente 表单分配给cliente

然后,从另一个表单中,将额外字段设置为分配给clienteservicio(如果我可以在一个表单中为一个cliente 处理每个servicio,那将是很棒的,每个@ 包含一行987654371@)

我现在的方式,不是我想要的方式......

【问题讨论】:

标签: php database symfony doctrine-orm entity-relationship


【解决方案1】:

来自 cmets 的回答仍然适用。

您只需要将您的 m:n 关系转换为 m:1 加 1:n 关系,您最终将得到 3 个实体而不是 2 个。一旦您拥有 3 个实体,您也可以创建一个新表单对于“中间”实体,因为它和其他所有实体一样。

更新:

如果您向客户端添加一些逻辑,您仍然可以模拟相同的事情:

public function addService(Service $service){
     $clientService = new ClientService();
     $clientService->setClient($this);
     $clientService->setService($service);
     $this->clientService->add($clientService);
}

你可以用getService()做一些类似的模拟;

另一种方法是您只需要采用您的表单并在您的客户表单上有多个客户服务,然后在每个客户服务表单上只有一项服务。这应该仍然有效。

【讨论】:

    猜你喜欢
    • 2011-12-29
    • 1970-01-01
    • 2019-01-22
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 2014-10-26
    • 2014-12-11
    • 1970-01-01
    相关资源
    最近更新 更多