如何解决原则ORM:复合键和外键作为主键
我正在尝试将组合键和外键作为在Doctrine ORM中工作的主键。我知道我正在尝试做的事情是可能的,因为它在此处进行了描述:https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/tutorials/composite-primary-keys.html#composite-and-foreign-keys-as-primary-key。这正是我的用例:我有一些产品,一个订单和一个订单项。
但是,准则orm无法将此关系映射到数据库。当前的问题是,已注释的\Id
主键中只有一个反映在MysqL数据库上。因此,$ producto正确转换为producto_id
到数据库,并且既是主键又是外键。但是,以相同方式注释的$orden
属性在我的数据库中什么都不会出现。
这似乎很奇怪,因为当我第一次测试此功能时,我仅尝试使用两个属性之一,并且效果很好,但是,当同时注释两个属性时,元数据解析器似乎只能解析其中一个。此外,我试图通过忘记外键而只拥有一个复合主键(就像我以前使用过的那样)来将项目恢复到可用状态,但是现在解析器似乎甚至无法识别主键。例如,对于:
class ProductoOrden
{
/**
* @ORM\Id()
* @ORM\Column(type="integer")
*/
private $idOrden;
/**
* @ORM\Id()
* @ORM\Column(type="integer")
*/
private $idProducto;
我得到:
bash-3.2$ PHP bin/console make:migration
In MappingException.PHP line 52:
No identifier/primary key specified for Entity "App\Entity\ProductoOrden". Every Entity must
have an identifier/primary key.
因此,我无法正确设置它或将其还原到以前的状态(这是最奇怪的状态)。
我要从头开始重新启动整个项目,因为我无法理解元数据解析的工作方式。我担心自己搞砸了,因为以前由于类似的问题,我已经手动擦除了'src \ Migrations'中的文件,而PHP bin/console doctrine:migrations:version --delete --all
似乎没有用,或者我不知道如何正确使用它
结论:¿有人可以断言我尝试使用ProducoOrden进行的操作是否可行(也许我不了解文档示例)?有什么方法可以完全清除以前关于注释/架构元数据的缓存?
我已经看过orm:schema-tool
了,但是我并没有真正了解如何正确配置它,或者为什么我必须在我的项目中已经全部使用bin/console
工具的所有原因。
为了完整起见,我将显示所有三个涉及的类,但是主要问题是在ProductoOrden(订单项)中。
<?PHP
//Products
namespace App\Entity;
use App\Repository\ProductosRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity(repositoryClass=ProductosRepository::class)
* @UniqueEntity("idProducto",message=" {producto {{ value }}}: llave primaria violada ")
*/
class Productos
{
/**
* @ORM\Id()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string",length=255)
*/
private $nombreProducto;
/**
* @ORM\Column(type="string",length=255)
*/
private $descripcionProducto;
/**
* @ORM\Column(type="string",length=255)
*/
private $urlImagen;
/**
* @ORM\Column(type="integer")
*/
private $puntosProducto;
public function getIdProducto(): ?int
{
return $this->idProducto;
}
public function getCodProducto(): ?int
{
return $this->idProducto;
}
public function setIdProducto(int $codProducto): self
{
$this->idProducto = $codProducto;
return $this;
}
public function getNombreProducto(): ?string
{
return $this->nombreProducto;
}
public function setNombreProducto(string $nombreProducto): self
{
$this->nombreProducto = $nombreProducto;
return $this;
}
public function getDescripcionProducto(): ?string
{
return $this->descripcionProducto;
}
public function setDescripcionProducto(string $descripcionProducto): self
{
$this->descripcionProducto = $descripcionProducto;
return $this;
}
public function getUrlImagen(): ?string
{
return $this->urlImagen;
}
public function setUrlImagen(string $urlImagen): self
{
$this->urlImagen = $urlImagen;
return $this;
}
public function getPuntosProducto(): ?int
{
return $this->puntosProducto;
}
public function setPuntosProducto(int $puntosProducto): self
{
$this->puntosProducto = $puntosProducto;
return $this;
}
public function __toString(){
$str = '{producto:'.$this->getIdProducto().',nombre: '.$this->getNombreProducto().'}';
return $str;
}
}
<?PHP
\\Orders
namespace App\Entity;
use App\Repository\OrdenesRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity(repositoryClass=OrdenesRepository::class)
* @UniqueEntity("idOrden",message="{orden {{ value }}}: llave primaria violada")
*/
class Ordenes
{
/**
* @ORM\Id()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="integer")
*/
private $totalOrden;
/**
* @ORM\Column(type="string",length=255)
*/
private $estado;
/**
* @ORM\OnetoMany(targetEntity=ProductoOrden::class,mappedBy="orden",orphanRemoval=true)
*/
private $productosOrden;
public function __construct()
{
$this->productosOrden = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getIdOrden(): ?int
{
return $this->idOrden;
}
public function setIdOrden(int $idOrden): self
{
$this->idOrden = $idOrden;
return $this;
}
public function getTotalOrden(): ?int
{
return $this->totalOrden;
}
public function setTotalOrden(int $totalOrden): self
{
$this->totalOrden = $totalOrden;
return $this;
}
public function getEstado(): ?string
{
return $this->estado;
}
public function setEstado(string $estado): self
{
$this->estado = $estado;
return $this;
}
public function __toString(){
$str = '{orden:'.$this->getIdOrden().'}';
return $str;
}
/**
* @return Collection|ProductoOrden[]
*/
public function getProductosOrden(): Collection
{
return $this->productosOrden;
}
public function addProductosOrden(ProductoOrden $productosOrden): self
{
if (!$this->productosOrden->contains($productosOrden)) {
$this->productosOrden[] = $productosOrden;
$productosOrden->setorden($this);
}
return $this;
}
public function removeProductosOrden(ProductoOrden $productosOrden): self
{
if ($this->productosOrden->contains($productosOrden)) {
$this->productosOrden->removeElement($productosOrden);
// set the owning side to null (unless already changed)
if ($productosOrden->getorden() === $this) {
$productosOrden->setorden(null);
}
}
return $this;
}
}
<?PHP
\\Order-items
namespace App\Entity;
use App\Repository\ProductoOrdenRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity(repositoryClass=ProductoOrdenRepository::class)
* @UniqueEntity(fields={"idOrden","idProducto"},message="{prod. orden {{ value }}}: llave primaria violada")
*/
class ProductoOrden
{
/*
* @ORM\Id
* @ORM\ManyToOne(targetEntity=Ordenes::class,inversedBy="productosOrden")
* @ORM\JoinColumn(nullable=false)
*/
private $orden;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity=Productos::class)
* @ORM\JoinColumn(nullable=false)
*/
private $producto;
/**
* @ORM\Column(type="integer")
*/
private $puntos;
/**
* @ORM\Column(type="integer")
*/
private $cantidad;
public function getId(): ?int
{
return $this->idOrden;
}
public function setIdOrden(int $idOrden): self
{
$this ->idOrden = $idOrden;
return $this;
}
public function getIdProducto(): ?int
{
return $this->idProducto;
}
public function setIdProducto(int $idProducto): self
{
$this->idProducto = $idProducto;
return $this;
}
public function getPuntos(): ?int
{
return $this->puntos;
}
public function setPuntos(int $puntos): self
{
$this->puntos = $puntos;
return $this;
}
public function getCantidad(): ?int
{
return $this->cantidad;
}
public function setCantidad(int $cantidad): self
{
$this->cantidad = $cantidad;
return $this;
}
public function __toString(){
$str = '{productoOrden:'.$this->getId().','.$this->getIdProducto().'}';
return $str;
}
public function getorden(): ?Ordenes
{
return $this->orden;
}
public function setorden(?Ordenes $orden): self
{
$this->orden = $orden;
return $this;
}
}
final class Version20200814210929 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}
public function up(Schema $schema) : void
{
// this up() migration is auto-generated,please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'MysqL','Migration can only be executed safely on \'MysqL\'.');
$this->addsql('ALTER TABLE producto_orden ADD puntos INT NOT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated,'Migration can only be executed safely on \'MysqL\'.');
$this->addsql('ALTER TABLE producto_orden DROP puntos');
}
}
如您所见,一些小的更改,例如更改属性作品的类型;但它似乎并没有采用id()和关联注释。
非常感谢
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。