0

我有几个带有 2 个主键的数据库表,id并且date. 我不更新记录,而是插入一条包含更新信息的新记录。此新记录具有相同id的字段,并且date字段为 NOW()。我将使用产品表来解释我的问题。

我希望能够在特定日期请求产品详细信息。因此,我在 DQL 中使用以下子查询,效果很好:

WHERE p.date = (
    SELECT MAX(pp.date)
    FROM Entity\Product pp
    WHERE pp.id = p.id
    AND pp.date < :date
)

此产品表有一些引用表,如类别。此类别表具有相同的iddate键组合。我希望能够在特定日期请求产品详细信息和类别详细信息。因此,我将如上所示的 DQL 扩展为以下内容,这也可以正常工作:

JOIN p.category c
WHERE p.date = (
    SELECT MAX(pp.date)
    FROM Entity\Product pp
    WHERE pp.id = p.id
    AND pp.date < :date
)
AND c.date = (
    SELECT MAX(cc.date)
    FROM Entity\ProductCategory cc
    WHERE cc.id = c.id
    AND cc.date < :date
)

但是,如您所见,如果我有多个引用的表,我将不得不复制同一个 DQL。我想以某种方式将这些子查询添加到实体中,以便每次调用实体时都会添加此子查询。

我曾想过以某种__construct($date)或某种setUp($date)方法添加它,但我有点卡在这里。另外,它会帮助添加@IdEntity\Product::date

我希望有一个人可以帮助我。我不期待一个完整的解决方案,非常感谢朝着好的方向迈出的一步。

4

1 回答 1

0

我想我已经找到了解决方案。诀窍是(首先,更新到 Doctrine 2.2 和)使用过滤器

namespace Filter;

use Doctrine\ORM\Mapping\ClassMetaData,
    Doctrine\ORM\Query\Filter\SQLFilter;

class VersionFilter extends SQLFilter {
    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias) {
        $return = $targetTableAlias . '.date = (
            SELECT MAX(sub.date)
            FROM ' . $targetEntity->table['name'] . ' sub
            WHERE sub.id = ' . $targetTableAlias . '.id
            AND sub.date < ' . $this->getParameter('date') . '
        )';

        return $return;
    }
}

将过滤器添加到配置中:

$configuration->addFilter("version", Filter\VersionFilter");

并在我的存储库中启用它:

$this->_em->getFilters()->enable("version")->setParameter('date', $date);
于 2012-07-30T14:26:05.487 回答