这是我在没有任何其他查询的情况下解决此问题的方法:
问题
需要将自定义 COUNT 字段添加到与 Symfony Pager 一起使用的典型结果集中。但是,正如我们所知,Propel 不支持此功能。所以简单的解决方案是在模板中做这样的事情:
foreach ($pager->getResults() as $project):
echo $project->getName() . ' and ' . $project->getNumMembers()
endforeach;
Where为每个对象getNumMembers()
运行一个单独的 COUNT 查询。$project
当然,我们知道这是非常低效的,因为您可以通过将其作为列添加到原始 SELECT 查询中来动态执行 COUNT,为显示的每个结果保存一个查询。
我有几个不同的页面显示这个结果集,都使用不同的标准。因此,直接用 PDO 编写我自己的 SQL 查询字符串会太麻烦,因为我必须进入 Criteria 对象并试图根据其中的任何内容来形成查询字符串!
所以,我最终所做的一切都避免了,让 Propel 的本机代码与 Criteria 一起工作并像往常一样创建 SQL。
1 - 首先在由 doSelect() 返回的模型对象中创建 [get/set]NumMembers() 等效访问器/修改器方法。请记住,访问器不再执行 COUNT 查询,它只是保存它的值。
2 - 进入对等类并覆盖父 doSelect() 方法,并完全复制其中的所有代码
3 - 删除此位,因为 getMixerPreSelectHook 是基本对等点的私有方法(或者如果需要,将其复制到对等点):
// symfony_behaviors behavior
foreach (sfMixer::getCallables(self::getMixerPreSelectHook(__FUNCTION__)) as $sf_hook)
{
call_user_func($sf_hook, 'BaseTsProjectPeer', $criteria, $con);
}
4 - 现在将您的自定义 COUNT 字段添加到对等类中的 doSelect 方法:
// copied into ProjectPeer - overrides BaseProjectPeer::doSelectJoinUser()
public static function doSelectJoinUser(Criteria $criteria, ...)
{
// copied from parent method, along with everything else
ProjectPeer::addSelectColumns($criteria);
$startcol = (ProjectPeer::NUM_COLUMNS - ProjectPeer::NUM_LAZY_LOAD_COLUMNS);
UserPeer::addSelectColumns($criteria);
// now add our custom COUNT column after all other columns have been added
// so as to not screw up Propel's position matching system when hydrating
// the Project and User objects.
$criteria->addSelectColumn('COUNT(' . ProjectMemberPeer::ID . ')');
// now add the GROUP BY clause to count members by project
$criteria->addGroupByColumn(self::ID);
// more parent code
...
// until we get to this bit inside the hydrating loop:
$obj1 = new $cls();
$obj1->hydrate($row);
// AND...hydrate our custom COUNT property (the last column)
$obj1->setNumMembers($row[count($row) - 1]);
// more code copied from parent
...
return $results;
}
就是这样。现在,您将额外的 COUNT 字段添加到您的对象中,而无需在吐出结果时执行单独的查询来获取它。此解决方案的唯一缺点是您必须复制所有父代码,因为您需要在其中添加位。但在我的情况下,这似乎是保存所有这些查询而不是编写我自己的 SQL 查询字符串的一个小妥协。