Tom*_*ohl 5 php orm propel symfony1
使用Propel对象的计算字段的最佳方法是什么?
假设我有一个对象"Customer",它有一个对应的表"customers",每列对应一个我对象的属性.我想要做的是:在View A上使用它时,在我的对象上添加一个计算属性"已完成订单数",但在视图B和C上没有.
计算的属性是通过ID链接到我的"客户"对象的"订单"对象的COUNT().
我现在可以做的是首先选择所有客户对象,然后迭代计算所有客户对象的订单,但我认为在单个查询中执行它会提高性能.但是我不能正确地"保湿"我的Propel对象,因为它不包含计算字段的定义.
你会怎么做?
有几种选择。首先,是在数据库中创建一个视图来为您进行计数,类似于我在这里的回答。我为当前正在从事的 Symfony 项目执行此操作,其中给定表的只读属性实际上比表本身宽得多。这是我的建议,因为分组列(max()、count() 等)无论如何都是只读的。
其他选项是将此功能实际构建到您的模型中。您绝对可以自己进行补水,但有点复杂。这是粗略的步骤
但是,这并不比您已经谈论的好多少。您仍然需要N + 1 次查询来检索单个记录集。但是,您可以在步骤 #3 中发挥创意,使N是计算的列数,而不是返回的行数。
另一种选择是在Table Peer 类上创建自定义选择方法。
这是此方法的一个示例
<?php
class TablePeer extends BaseTablePeer
{
public static function selectWithCalculatedColumns()
{
// Do our custom selection, still using propel's column data constants
$sql = "
SELECT " . implode( ', ', self::getFieldNames( BasePeer::TYPE_COLNAME ) ) . "
, count(" . JoinedTablePeer::ID . ") AS calc_col
FROM " . self::TABLE_NAME . "
LEFT JOIN " . JoinedTablePeer::TABLE_NAME . "
ON " . JoinedTablePeer::ID . " = " . self::FKEY_COLUMN
;
// Get the result set
$conn = Propel::getConnection();
$stmt = $conn->prepareStatement( $sql );
$rs = $stmt->executeQuery( array(), ResultSet::FETCHMODE_NUM );
// Create an empty rowset
$rowset = array();
// Iterate over the result set
while ( $rs->next() )
{
// Create each row individually
$row = new Table();
$startcol = $row->hydrate( $rs );
// Use our custom setter to populate the new column
$row->setCalcCol( $row->get( $startcol ) );
$rowset[] = $row;
}
return $rowset;
}
}
Run Code Online (Sandbox Code Playgroud)
您的问题可能还有其他解决方案,但超出了我的知识范围。祝你好运!