已定义联接类-p上的Doctrine QueryBuilder indexBy错误



使用symfony2/doctrine2,我很难为查询定义索引。

我的代码:

$queryBuilder = $this->_em
->createQueryBuilder()
->select('u, uis, cost, p, stock')
->from('AppBundle:FoodAnalyticsUserIngredient', 'u', 'p.id')
->leftJoin('u.product', 'p')
->leftJoin('u.numberObjects', 'stock')
->leftJoin('u.userIngredientSuppliers', 'uis')
->leftJoin('uis.numberObjects', 'cost')
->where('u.user = ?1')
->setParameter(1, $portfolioUser)
;

我得到以下错误:

[Semantical Error] line 0, col 110 near 'p LEFT JOIN u.numberObjects': Error: 'p' is already defined.
500 Internal Server Error - QueryException
1 linked Exception: QueryException »
[1/2] QueryException: SELECT u, uis, cost, p, stock FROM AppBundle:FoodAnalyticsUserIngredient u INDEX BY p.id LEFT JOIN u.product p LEFT JOIN u.numberObjects stock LEFT JOIN u.userIngredientSuppliers uis LEFT JOIN uis.numberObjects cost WHERE u.user = ?1   +

使用u.product,我得到以下错误:

[Semantical Error] line 0, col 87 near 'product LEFT': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
500 Internal Server Error - QueryException
1 linked Exception: QueryException »

仅使用product,我得到以下错误:

[Semantical Error] line 0, col 85 near 'product LEFT': Error: 'product' does not point to a Class.
500 Internal Server Error - QueryException
1 linked Exception: QueryException »

如果我使用u.id,效果会很好我只能使用同一表中某个字段的索引吗?

我该怎么做才能让它正常工作?

Thansk很多!

编辑:

作为临时修复,我正在使用:

$result = $queryBuilder->getQuery()->getResult();
$result = array_combine(array_map(function(UserIngredient $userIngredient){
return $userIngredient->getProduct()->getId();
}, $result), $result);
return $result;

属性indexBy仅适用于您当前选择的实体,正如您所猜测的(以及AFAIK);所以在您的情况下,您只能通过u.id进行索引。

这对我来说是有意义的,因为从其他实体进行索引确实会打乱返回的结果。唯一能得到正确结果的情况是:

  • 来自主实体和"目标"indexBy实体的所有联接都是一对一的
  • 所有联接都是INNER join
  • 结果集的indexBy列是唯一的

在其他任何情况下,你都会在水合过程中失去一些实例参考。

在您的示例中,您正在使用LEFT JOIN:没有产品的所有实体会发生什么?全部丢弃,所以LEFT JOIN将具有类似INNER JOIN的worker。此外,您的变通方法建议您希望将具有相同索引的实体组合在一起,但这不是Doctrine的工作方式:在Doctrine中,indexBy列必须是唯一的。有关更多信息,请参阅官方文档。

请注意,您可以在JOIN子句中indexByp.id,但这有不同的含义。这意味着,当对UserIngredients实例进行水合时,产品集合应该通过id进行索引。

因此,我的建议是遵循以下两种解决方案之一:

  • 放弃Doctrine indexBy,使用您的工作环境
  • 如果有反向关联Product -> UserIngredients,请使用Product作为查询的主要实体(from子句,首先出现在select中),然后按p.id进行索引

使用哪一个取决于您的业务逻辑,但我通常更喜欢第二个解决方案,因为第一个解决方案生成多级数组,它们可以更好地用实体关系表示。

希望得到帮助!:)

相关内容

  • 没有找到相关文章

最新更新