1

问题:

如何将主键绑定到自定义关系查询?

上下文,用于:

一个来源可以与多个不同的修改 (MANY_MANY) 相关,每个修改都与某个产品 (BELONGS_TO) 相关。如果多个产品有一个来源,则意味着这些产品是相同的——这就是标准。(我不能只是合并相同的产品,因为结果可能它们不一样,但如果我合并它们 - 我不能将它们拆分回来)。

因此,当我需要查找与某个产品相关的所有订单时,我实际上想查找具有相同产品的所有订单,而不仅仅是当前产品。

关系如下所示:

'orderedProducts'=>array(self::HAS_MANY,'OrderProduct','','on'=>('modification_id IN (
select DISTINCT ms2.modification_id FROM products p1
LEFT JOIN products_modifications pm ON pm.product_id = p1.product_id
LEFT JOIN modifications_sources ms ON ms.modification_id = pm.modification_id
LEFT JOIN modifications_sources ms2 ON ms2.source_id = ms.source_id
where p1.product_id='.$this->primaryKey.'
)')),

'orders'=>array(self::HAS_MANY,'Order',array('order_id'=>'order_id'),'through'=>'orderedProducts'),

$this->primaryKey 不起作用,这里只是为了显示我需要绑定主键的位置。

有什么建议如何绑定主键吗?

4

1 回答 1

1

这是一个相当复杂的查询,通过为模型定义 getter getOrderedProducts() 来实现这个功能会非常方便。在这个 getter 中,您可以简单地通过 $this->primaryKey 获取模型的主键。然后,您将能够通过属性 $model->orderedProject 从您的模型中获取您订购的产品,就像您使用关系一样。而且,作为一些奖励,您可以为此类繁重的查询实现一些缓存。

至于关系,我通过将查询记录到访问模型的 HAS_MANY 关系字段时构造的 SQL 进行的研究表明,YII 会将模型的主键绑定到命名参数之一:ypl0、:ypl1...等. 所以,如果你觉得一些肮脏的 hack 没问题,你可以通过绑定参数访问你模型的主键:

'orderedProducts'=>array(self::HAS_MANY,'OrderProduct','','on'=>('modification_id IN (
select DISTINCT ms2.modification_id FROM products p1
LEFT JOIN products_modifications pm ON pm.product_id = p1.product_id
LEFT JOIN modifications_sources ms ON ms.modification_id = pm.modification_id
LEFT JOIN modifications_sources ms2 ON ms2.source_id = ms.source_id
where p1.product_id=:ypl0'

但是,您应该确保 YII 将主键绑定到他的参数的第一个 (:ypl0)(如果您自己不绑定任何参数,那将是真的)。无论如何,我宁愿推荐通过将 getter 定义为更稳定和可定制的方式来依赖第一种方法。

于 2013-07-23T10:11:44.877 回答