尝试使用 Symfony 创建一个允许我访问外键对象的查询
Trying to create a query with Symfony that allows me to access object of foreign key
所以我有 3 个实体:
超市:
|编号 | supermarket_name |
类别:
|编号 | category_name |
产品:
|编号 | product_name | supermarket_id | category_id |
supermarket_id 和 category_id 分别与超市和类别的 id 多对一。
我希望这样当我 select 一家超市时,我可以获得该超市下方列出的所有类别。我一直在尝试通过已传递到我的 ProductRepository.php 文件中的查询方法的超市 id 从产品实体进行查询来获取此数据,如果我有以下内容,该文件将成功运行:
public function findAllCategoriesBySupermarket($supermarketId)
{
return $this->getEntityManager()
->createQuery(
"SELECT p
FROM AppBundle:Product p
WHERE p.supermarketId = $supermarketId"
)
->getResult();
}
然后我可以在我的视图中循环成功地显示产品:
{{ product.categoryId.categoryName }}
问题是因为我是从产品中查询的,所以我最终会得到不止一个相同的类别,因为可以将多个产品分配到同一类别,所以我试图通过向类别:
public function findAllCategoriesBySupermarket($supermarketId)
{
return $this->getEntityManager()
->createQuery(
"SELECT DISTINCT p.categoryId
FROM AppBundle:Product p
WHERE p.supermarketId = $supermarketId"
)
->getResult();
}
当我在 phpmyadmin 中测试它时它工作正常但不幸的是 symfony 给出了以下错误:
[Semantical Error] line 0, col 18 near 'categoryId
': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
不确定我该如何解决这个问题,因为我已经尝试了很多不同的方法,但都没有成功。任何关于我如何解决这个问题的建议都将不胜感激!
问题是您不能通过 属性 在学说中 select 一个不同的实体关联。但是,您可以 select 不同的身份。假设您想要实体而不仅仅是 ID...
为此,您需要将两个实体之间的关联定义为双向关联。
由于您在 Product.category
上有关联但与 Category.products
没有关联,因此您需要创建它。
/**
* @ORM\Entity
*/
class Category
{
//...
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Product", mappedBy="category")
*/
private $products;
public function __construct()
{
$this->products = new \Doctrine\Common\Collections\ArrayCollection;
}
//...
/**
* get Products
* @return Product[]|ArrayCollection
*/
public function getProducts()
{
return $this->products;
}
/**
* add Product
* @param Product $product
* @return $this
*/
public function addProduct(Product $product)
{
$this->products->add($product);
return $this;
}
/**
* remove Product
* @param Product $product
* @return $this
*/
public function removeProduct(Product $product)
{
$this->products->removeElement($product);
return $this;
}
}
然后在您的 Product.category
属性
中加入协会 inversedBy
/**
* @ORM\Entity
*/
class Product
{
//...
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Category", inversedBy="products")
* @ORM\JoinColumn(name="category", referencedColumnName="id")
*/
private $category;
//...
}
您也不能 select 没有根关联的关联实体。
例如
SELECT DISTINCT c
FROM AppBundle:Product p
JOIN p.category c
'SELECT DISTINCT': Error: Cannot select entity through identification variables without choosing at least one root entity alias.
因此,要检索与指定超市的产品关联的不同类别,您可以像这样编写 DQL。
public function findAllCategoriesBySupermarket($supermarketId)
{
return $this->_em->createQuery(
'SELECT c
FROM AppBundle:Category c
JOIN c.products p WITH p.supermarketId = :supermarket'
)
->setParameter('supermarket', $supermarketId)
->getResult();
}
虽然我想指出,DISTINCT
标志在这种情况下是多余的,因为它仅隐含在 select 类别 (c) 中。
您也可以使用 SELECT c, p
来获取一系列类别及其相关产品。
{% for category in categories %}
{{ category.name }}:
{% for product in category.products %}
{{ product.name }}
{% endfor %}
{% endfor %}
或者,要保留单向关系,您需要使用子查询。但是您将失去检索 Category.products
关联的能力,如上所示。
SELECT c
FROM AppBundle:Category c
WHERE c.id IN (
SELECT DISTINCT IDENTITY(p.categoryId)
FROM AppBundle:Product p
WHERE p.supermarketId = :supermarket
)
所以我有 3 个实体:
超市:
|编号 | supermarket_name |
类别:
|编号 | category_name |
产品:
|编号 | product_name | supermarket_id | category_id |
supermarket_id 和 category_id 分别与超市和类别的 id 多对一。
我希望这样当我 select 一家超市时,我可以获得该超市下方列出的所有类别。我一直在尝试通过已传递到我的 ProductRepository.php 文件中的查询方法的超市 id 从产品实体进行查询来获取此数据,如果我有以下内容,该文件将成功运行:
public function findAllCategoriesBySupermarket($supermarketId)
{
return $this->getEntityManager()
->createQuery(
"SELECT p
FROM AppBundle:Product p
WHERE p.supermarketId = $supermarketId"
)
->getResult();
}
然后我可以在我的视图中循环成功地显示产品:
{{ product.categoryId.categoryName }}
问题是因为我是从产品中查询的,所以我最终会得到不止一个相同的类别,因为可以将多个产品分配到同一类别,所以我试图通过向类别:
public function findAllCategoriesBySupermarket($supermarketId)
{
return $this->getEntityManager()
->createQuery(
"SELECT DISTINCT p.categoryId
FROM AppBundle:Product p
WHERE p.supermarketId = $supermarketId"
)
->getResult();
}
当我在 phpmyadmin 中测试它时它工作正常但不幸的是 symfony 给出了以下错误:
[Semantical Error] line 0, col 18 near 'categoryId
': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
不确定我该如何解决这个问题,因为我已经尝试了很多不同的方法,但都没有成功。任何关于我如何解决这个问题的建议都将不胜感激!
问题是您不能通过 属性 在学说中 select 一个不同的实体关联。但是,您可以 select 不同的身份。假设您想要实体而不仅仅是 ID...
为此,您需要将两个实体之间的关联定义为双向关联。
由于您在 Product.category
上有关联但与 Category.products
没有关联,因此您需要创建它。
/**
* @ORM\Entity
*/
class Category
{
//...
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Product", mappedBy="category")
*/
private $products;
public function __construct()
{
$this->products = new \Doctrine\Common\Collections\ArrayCollection;
}
//...
/**
* get Products
* @return Product[]|ArrayCollection
*/
public function getProducts()
{
return $this->products;
}
/**
* add Product
* @param Product $product
* @return $this
*/
public function addProduct(Product $product)
{
$this->products->add($product);
return $this;
}
/**
* remove Product
* @param Product $product
* @return $this
*/
public function removeProduct(Product $product)
{
$this->products->removeElement($product);
return $this;
}
}
然后在您的 Product.category
属性
inversedBy
/**
* @ORM\Entity
*/
class Product
{
//...
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Category", inversedBy="products")
* @ORM\JoinColumn(name="category", referencedColumnName="id")
*/
private $category;
//...
}
您也不能 select 没有根关联的关联实体。 例如
SELECT DISTINCT c
FROM AppBundle:Product p
JOIN p.category c
'SELECT DISTINCT': Error: Cannot select entity through identification variables without choosing at least one root entity alias.
因此,要检索与指定超市的产品关联的不同类别,您可以像这样编写 DQL。
public function findAllCategoriesBySupermarket($supermarketId)
{
return $this->_em->createQuery(
'SELECT c
FROM AppBundle:Category c
JOIN c.products p WITH p.supermarketId = :supermarket'
)
->setParameter('supermarket', $supermarketId)
->getResult();
}
虽然我想指出,DISTINCT
标志在这种情况下是多余的,因为它仅隐含在 select 类别 (c) 中。
您也可以使用 SELECT c, p
来获取一系列类别及其相关产品。
{% for category in categories %}
{{ category.name }}:
{% for product in category.products %}
{{ product.name }}
{% endfor %}
{% endfor %}
或者,要保留单向关系,您需要使用子查询。但是您将失去检索 Category.products
关联的能力,如上所示。
SELECT c
FROM AppBundle:Category c
WHERE c.id IN (
SELECT DISTINCT IDENTITY(p.categoryId)
FROM AppBundle:Product p
WHERE p.supermarketId = :supermarket
)