我使用symfony + sqllite来测试我的应用程序,我遇到了ORM问题。 Doctrine在JOIN中生成带有双ON的sql,类似于:
SELECT s0_.config AS config_0,s0_.sensor_number AS sensor_number_1 来自传感器s0_ LEFT JOIN fos_user f1_ LEFT JOIN worker w2_ ON f1_.id = w2_.id LEFT JOIN经销商d3_ ON f1_.id = d3_.id ON(s0_.owner_id = f1_.id)AND(f1_.status!=' d')LEFT JOIN user_groups u4_ ON (f1_.user_group_id = u4_.id)AND(u4_.status!=' d')WHERE(s0_.status) =?和u4_.id =? AND((s0_.device_id IS NULL或s0_.device_id =?)))AND((从fos_user中选择user_group_id,其中id = s0_.owner_id)= ' 1')和(s0_.status!=' d')
它是关于:
ON f1_.id = d3_.id ON (s0_.owner_id = f1_.id)
导致错误:
SQLSTATE [HY000]:一般错误:1接近\" ON \":语法错误","类":" Doctrine \ DBAL \ Exception \ SyntaxErrorException"
我查了一下,我发现SQLite不能使用多个" ON"(postgresSQL的工作原理),所以为什么doctrine会在运行测试时生成它。
Symfony表格负责此事:
$builder->add(
'sensors',
EntityType::class,
[
'class' => Sensors::class,
'label' => 'form.assigned-sensors',
'required' => false,
'multiple' => true,
'by_reference' => false,
'query_builder' => function (EntityRepository $er) use ($device, $userGroup) {
$qb = $er->createQueryBuilder('s')
->leftJoin(User::class, 'o', 'WITH', 's.owner = o.id')
->leftJoin(UserGroups::class, 'g', 'WITH', 'o.userGroup = g.id')
->where('s.status = :status')
->andWhere('g.id = :userGroupId')
->andWhere('(s.device is null or s.device = :deviceId)')
->setParameter('status', 'a')
->setParameter('deviceId', $device->getId())
->setParameter('userGroupId', $userGroup->getId());
return $qb;
},
]
);
编辑:
最后我发现了以下答案中描述的问题。谢谢你的时间。
答案 0 :(得分:0)
最后我在这张票中找到了问题:
https://stackoverflow.com/a/15088250/6357312
没有必要这样做:
- > leftJoin(User :: class,'o','WITH','s.owner = o.id')
应该只是:
- > leftJoin('s.owner','o')
实体已在此关系上定义了哪个表与所选实体建立关系。
最后这段代码如下:
$builder->add(
'sensors',
EntityType::class,
[
'class' => Sensors::class,
'label' => 'form.assigned-sensors',
'required' => false,
'multiple' => true,
'by_reference' => false,
'query_builder' => function (EntityRepository $er) use ($device, $userGroup) {
$qb = $er->createQueryBuilder('s')
->leftJoin('s.owner', 'o')
->leftJoin('o.userGroup', 'g')
->andWhere('g.id = :userGroupId')
->andWhere('(s.device is null or s.device = :deviceId)')
->setParameter('userGroupId', $userGroup->getId())
->setParameter('deviceId', $device->getId());
return $qb;
},
]
);