【发布时间】:2019-12-08 13:55:56
【问题描述】:
我刚刚开始我的第一个 symfony 项目,我有点困惑。
我想查询数据库中没有产品的货架。 我想出了这样的 sql 查询,它似乎有效:
select distinct she.id shelf_id,rac.id rack_id , row.id row_id, war.id warehouse_id from shelfs she
left join products pro on she.id = pro.warehouse_id
left join racks rac on she.rack_id=rac.id
left join rows row on rac.row_id = row.id
left join warehouses war on row.warehouse_id = war.id
where she.id not in (select shelf_id from products);
但我不知道如何将其翻译成 dql。
我曾尝试在 Repository 中编写这样的函数:
{
$entityManager = $this->getEntityManager();
$query = $entityManager->createQuery(
'SELECT distinct she
FROM App\Entity\Shelfs she
JOIN App\Entity\Racks rac
JOIN App\Entity\Rows row
JOIN App\Entity\Warehouses war
WHERE she NOT IN (SELECT prod FROM App\Entity\Products prod)
');
return $query->getResult();
}
这是部分工作,因为起初它显示了 sql 查询所做的确切值。 例如 3 Shelf id,上面没有产品。 但是当我将产品添加到其中一个货架时,它仍然显示 3 个是空的。
那是我的控制器:
public function index()
{
$repository = $this->getDoctrine()->getRepository(Products::class);
$product = $repository->find(76); // that's for testing and it is refreshing
$warehousesRepository = $this->getDoctrine()
->getRepository(Warehouses::class);
$freespace = $warehousesRepository->findempty(); // that is not refreshing
return $this->render('base.html.twig', [
'selected_view' => 'pages/findPlace.html.twig',
'product' => $product,
'freespace' => $freespace
]);
}
这是我的产品实体:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\ProductsRepository")
*/
class Products
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="integer")
*/
private $barcode;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\Column(type="float")
*/
private $price;
/**
* @ORM\Column(type="integer")
*/
private $quantity;
/**
* @ORM\Column(type="integer")
* @ORM\ManyToOne(targetEntity="Warehouses")
* @ORM\JoinColumn(name="warehouse_id", referencedColumnName="id")
*/
private $warehouse_id;
/**
* @ORM\Column(type="integer")
* @ORM\ManyToOne(targetEntity="Rows")
* @ORM\JoinColumn(name="row_id", referencedColumnName="id")
*/
private $row_id;
/**
* @ORM\Column(type="integer")
* @ORM\ManyToOne(targetEntity="Racks")
* @ORM\JoinColumn(name="rack_id", referencedColumnName="id")
*/
private $rack_id;
/**
* @ORM\Column(type="integer")
* @ORM\ManyToOne(targetEntity="Shelfs")
* @ORM\JoinColumn(name="shelf_id", referencedColumnName="id")
*/
private $shelf_id;
public function getId(): ?int
{
return $this->id;
}
public function getBarcode(): ?int
{
return $this->barcode;
}
public function setBarcode(int $barcode): self
{
$this->barcode = $barcode;
return $this;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getPrice(): ?float
{
return $this->price;
}
public function setPrice(float $price): self
{
$this->price = $price;
return $this;
}
public function getQuantity(): ?int
{
return $this->quantity;
}
public function setQuantity(int $quantity): self
{
$this->quantity = $quantity;
return $this;
}
public function getWarehouseId(): ?int
{
return $this->warehouse_id;
}
public function setWarehouseId(int $warehouse_id): self
{
$this->warehouse_id = $warehouse_id;
return $this;
}
public function getRowId(): ?int
{
return $this->row_id;
}
public function setRowId(int $row_id): self
{
$this->row_id = $row_id;
return $this;
}
public function getRackId(): ?int
{
return $this->rack_id;
}
public function setRackId(int $rack_id): self
{
$this->rack_id = $rack_id;
return $this;
}
public function getShelfId(): ?int
{
return $this->shelf_id;
}
public function setShelfId(int $shelf_id): self
{
$this->shelf_id = $shelf_id;
return $this;
}
}
我尝试在创建实体后通过添加来建立关系:
* @ORM\ManyToOne(targetEntity="Warehouses")
* @ORM\JoinColumn(name="warehouse_id", referencedColumnName="id")
但这不起作用,所以我想我需要重做我的实体并在向导中指定关系。
我已经使用 sql 建立了关系:
ALTER TABLE shelfs ADD FOREIGN KEY (rack_id) REFERENCES racks(id);
ALTER TABLE racks ADD FOREIGN KEY (row_id) REFERENCES rows(id);
ALTER TABLE rows ADD FOREIGN KEY (warehouse_id) REFERENCES warehouses(id);
ALTER TABLE products ADD FOREIGN KEY (warehouse_id) REFERENCES warehouses(id);
ALTER TABLE products ADD FOREIGN KEY (rack_id) REFERENCES racks(id);
ALTER TABLE products ADD FOREIGN KEY (row_id) REFERENCES rows(id);
ALTER TABLE products ADD FOREIGN KEY (shelf_id) REFERENCES shelfs(id);
ALTER TABLE order_items ADD FOREIGN KEY (product_id) REFERENCES products(id);
ALTER TABLE order_items ADD FOREIGN KEY (order_id) REFERENCES orders(id);
ALTER TABLE orders ADD FOREIGN KEY (user_id) REFERENCES users(id);
它应该看起来像这样:
我觉得我在某个地方迷路了。
我不知道发生了什么,我在 symfony 文档中找不到任何相关内容。
【问题讨论】:
-
请发布您的实体代码,以便我们确定关联。使用学说时,您将使用
JOIN she.racks AS rac和JOIN racks.rows AS row等实体之间的关联关系。否则在指定实体命名空间时,您将指定一个连接子句JOIN App\Entity\Racks AS rac WITH she.rackId = rac.id -
至于教程,SO不太适合要求这样的东西。然而 SymfonyCasts 是一个很好的资源。
-
如果有帮助,您可以将 SQL 与带有 Native Queries 和 ResultSetMapper 的 Doctrine 一起使用。此外,您可能需要重新考虑您的模型。由于价格与产品相关,但更改产品价格的订单项目不会(追溯)更改订单项目的价格,从而导致错误订单。
-
同意,订购商品的价格和名称至少应该是静态条目,以避免在相关
product更改时更新关系。 Symfony 只是一个框架,它允许您使用 Doctrine ORM 来映射您的数据库。 ORM 专门用于业务逻辑,作为一种更方便的手段。出于报告目的,坚持使用本机 SQL 查询。至于教程请通过Doctrine tutorial -
您只需要指定
ORM\JoinColumn而不是ORM\Column,原则将读取referencedColumnName实体属性的注释。还鼓励首先映射您的实体及其关系,然后执行doctrine:schema:update命令(或使用学说迁移)在您的数据库中创建表结构。
标签: php sql symfony doctrine dql