且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Symfony应用程序-如何将计算字段添加到Propel对象?

更新时间:2023-11-30 23:16:22

有几种选择.首先,是在数据库中创建一个视图,该视图将为您完成计数,类似于我在此处的答案.我是针对当前的Symfony项目执行此操作的,在该项目中,给定表的只读属性实际上比表本身宽得多.这是我的建议,因为分组列(max(),count()等)始终是只读的.

There are several choices. First, is to create a view in your DB that will do the counts for you, similar to my answer here. I do this for a current Symfony project I work on where the read-only attributes for a given table are actually much, much wider than the table itself. This is my recommendation since grouping columns (max(), count(), etc) are read-only anyway.

其他选项实际上是将此功能构建到模型中.您绝对可以自己进行保湿,但是有点复杂.这是粗糙的步骤

The other options are to actually build this functionality into your model. You absolutely CAN do this hydration yourself, but it's a bit complicated. Here's the rough steps

  1. 将列作为受保护的数据成员添加到您的 Table 类中.
  2. 为这些列写适当的吸气剂和吸气剂
  3. 覆盖水合物方法,并在其中用来自其他查询的数据填充新列.确保将parent :: hydrate()作为第一行
  1. Add the columns to your Table class as protected data members.
  2. Write the appropriate getters and setters for these columns
  3. Override the hydrate method and within, populate your new columns with the data from other queries. Make sure to call parent::hydrate() as the first line

但是,这并没有比您正在谈论的要好得多.您仍然需要 N + 1个查询来检索单个记录集.但是,您可以在第3步中发挥创意,使 N 是计算的列数,而不是返回的行数.

However, this isn't much better than what you're talking about already. You'll still need N + 1 queries to retrieve a single record set. However, you can get creative in step #3 so that N is the number of calculated columns, not the number of rows returned.

另一种选择是在 Table Peer类上创建自定义选择方法.

Another option is to create a custom selection method on your TablePeer class.

  1. 从上方执行步骤1和2.
  2. 编写您将通过Propel :: getConnection()流程手动查询的自定义SQL.
  3. 通过遍历结果集手动创建数据集,并在此时处理自定义水合,以确保在doSelect流程使用时不会破坏水合.

这是这种方法的一个例子

Here's an example of this approach

<?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;
    }
}

对于您的问题,可能还有其他解决方案,但是这些解决方案是我所不了解的.祝你好运!

There may be other solutions to your problem, but they are beyond my knowledge. Best of luck!