我的Doctrine应用程序的一项新功能允许用户添加文档并使用较新的版本更新文档。
Document <-1--m-> DocumentVersion
用户可以设置文档版本有效的日期范围。因此,文档版本有效
该实体具有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
列:
我能够适应教义查询,但是找不到将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的文档中所述。但是我想知道是否真的没有办法正确映射计算值。也许写一个自定义的水龙头?