原则:选择标量/计算值

时间:2019-04-03 06:37:25

标签: doctrine-orm doctrine doctrine-query

我的Doctrine应用程序的一项新功能允许用户添加文档并使用较新的版本更新文档。

Document <-1--m-> DocumentVersion

用户可以设置文档版本有效的日期范围。因此,文档版本有效

  1. 这是最新版本
  2. 在有效日期范围内(如果已设置)

该实体具有getInvalid()方法,该方法允许稍后在视图中进行检查。要设置该字段,我编写了一个MySQL查询:

SELECT
  IF(
    (dv.valid_begin IS NULL OR (NOW() >= dv.valid_begin)) AND
    (dv.valid_end IS NULL OR(NOW() <= dv.valid_end))
    AND MAX(dv2.value) = dv.value
  , 0, 1) AS invalid,
  d.id, dv.id AS document_version_id,
  MAX(dv2.value) AS current_version,
  dv.valid_begin, dv.valid_end
FROM document d
INNER JOIN document_version dv ON dv.document_id = d.id
INNER JOIN document_version dv2 ON dv2.document_id = d.id
GROUP BY d.id, dv.id

该查询比较棘手,它使用第二个帮助程序联接(dv2)来确定当前版本。它按我的测试数据预期的那样填充了invalid列:

query result

我能够适应教义查询,但是找不到将invalid列值写入相应实体字段的方法:

$repo = $this->getDoctrine()->getRepository('AppBundle:Document');
$qb = $repo->createQueryBuilder('d')->select('d');
$qb->innerJoin('d.documentVersion', 'v');
$qb->innerJoin('d.documentVersion', 'v_temp');
$qb->addSelect('v', 'CASE WHEN
    MAX(v_temp.value) = v.value AND
        (v.valid_begin IS NULL OR (NOW() >= v.valid_begin)) AND
        (v.valid_end IS NULL OR (NOW() <= v.valid_end))
    THEN 0 ELSE 1 END AS invalid
');
$qb->groupBy('d.id, v.id');

Doctrine将invalid分别写入查询结果。该值已无意义,因为我们需要为每个文档版本提供一个值,但为所有文档版本提供一个值:

Doctrine's query result

是的,我知道-这是正确的行为,如Doctrine的文档中所述。但是我想知道是否真的没有办法正确映射计算值。也许写一个自定义的水龙头?

0 个答案:

没有答案