有趣的是,使用过的平面表只设置了一次就不会更改,这对于EAV来说是有效的,因为表名不会更改,而对于平面表则不会,因为表名包含商店ID。一种解决方法是制作一个辅助程序,以换出查询的FROM部分中的表。这是一个这样的助手的例子:
class My_Module_Helper_Data extends Mage_Core_Helper_Abstract
{
public function getProductCollectionForStore($store)
{
$collection = Mage::getResourceModel('catalog/product_collection');
// Change the store on the entity
// This doesn't change it in the (already constructed) SQL query
$collection->setStore($store);
if (! $collection->isEnabledFlat()) {
return $collection;
}
// Change the used table to the $store we want
$select = $collection->getSelect();
$from = $select->getPart('from');
// Here, getFlatTableName() will pick up the store set above
$from[$collection::MAIN_TABLE_ALIAS]['table'] =
$from[$collection::MAIN_TABLE_ALIAS]['tableName'] =
$collection->getEntity()->getFlatTableName();
$select->setPart('from', $from);
return $collection;
}
}
然后,您可以将其简单地用于:
$collection = Mage::helper('my_module')->getProductCollectionForStore('somestore')
->addAttributeToSelect('name');
我想这不会对SQL造成麻烦,因为您可以从单个平面表中获取所有数据,但是由于它是一个单例,因此最后使用的存储将在其他地方使用。
另一种解决方案是使观察者在catalog_product_collection_load_before
其上执行以下操作:
class My_Module_Model_Observer
{
public function setCorrectFlatStore(Varien_Event_Observer $observer)
{
$collection = $observer->getCollection();
if (! $collection->isEnabledFlat()) {
return;
}
$select = $collection->getSelect();
$from = $select->getPart('from');
// If somebody called setStore() on the collection make sure
// to update the used flat table
$from[$collection::MAIN_TABLE_ALIAS]['table'] =
$from[$collection::MAIN_TABLE_ALIAS]['tableName'] =
$collection->getEntity()->getFlatTableName();
$select->setPart('from', $from);
}
}
我同意Magento家伙应该在_beforeLoad()
方法中解决此问题。