Arn*_*aud 0 doctrine dql formbuilder symfony
在Symfony2中的表单类型中,我想包含一个带有查询构建器的实体字段,以便选择要显示的行.我的查询很复杂,我无法找到一种方法来使用查询构建器,我想使用DQL.不幸的是,我不能这样做$repository->createQuery(...)
,也没有$repository->getEntityManager()->createQuery()
.只有$repository->createQueryBuilder(...)
作品.有没有解决的办法?
顺便说一句,如果你碰巧找到一种更聪明的方式来执行我的SQL请求,这将非常有用(但这不是这个问题的主题!)
public function buildForm(FormBuilderInterface $builder, array $options)
{
$user = $this->user;
$builder
->add('friend', 'entity',
array(
'class' => 'MyappUserBundle:User',
'label' => 'User',
'query_builder' => function(EntityRepository $repository) use ($user) {
$query = $repository->getEntityManager()->createQuery("
SELECT u
FROM MyappUserBundle:User u
WHERE
u.id NOT IN (SELECT friend FROM MyappUserBundle:Friendrequest WHERE user = :user)
AND
u.id NOT IN (SELECT user FROM MyappUserBundle:Friendrequest WHERE friend = :user)
AND
u.id != :user
")
->setParameter('user', $user)
;
return $query;
}
)
)
;
}
Run Code Online (Sandbox Code Playgroud)
如何解决query_builder
问题(以及一般问题)
我们知道我们可以访问EntityRepository
您实体的类.因此,我们可以轻松找到可公开访问的方法.
因此,我们可以在Google上搜索"doctrine api entityrepository",它将我们引导到doctrine网站上的EntityRepository类API文档.
在该页面上,我们可以找到可公开访问的方法,您可以找到有关创建查询的3种方法,其中之一是createNativeNamedQuery
.
根据文档,这个方法返回一个实例Doctrine\ORM\NativeQuery
,点击它导致另一个页面与其他方法.您可以看到它NativeQuery
有一个setQuery
方法,并从Doctrine\ORM\AbstractQuery
其他方法列表继承.
现在,我们可能拥有我们需要的所有信息,因此我们可以提出一个可能有效的解决方案(如果没有那么我们可能真的非常接近).
// The closure expects \Doctrine\ORM\QueryBuilder to be returned
// so we need to create a named query first then create a list of ids
// and pass it to a query builder.
'query_builder' => function(EntityRepository $repository) use ($user) {
// Query for user ids with sub queries
$results = $repository
->createNativeNamedQuery('u')
->setSQL("
SELECT u.id
FROM user AS u
WHERE u.id NOT IN (
SELECT friend FROM friend_request_table WHERE user = :user
)
AND u.id NOT IN (
SELECT user FROM friend_request_table WHERE friend = :user
)
AND u.id != :user
")
->setParameter('user', $user->getId())
->getArrayResult();
// Build an array of IDs
$ids = array_map(function ($row) {
return $row['id'];
}, $results);
// Returns a QueryBuilder
return $repository->createQueryBuilder('u')
->where('u.id IN (:ids)')
->setParameter('ids', $ids);
}
Run Code Online (Sandbox Code Playgroud)
缺点是执行了两个查询.期望QueryBuilder
返回闭包,因此我们需要先创建一个原始查询,然后将结果传递给QueryBuilder
.
最重要的是,本机查询意味着原始SQL查询,因此您不能使用实体注释,并且不同的数据库可能不支持您的查询.
如果你喜欢我的意见,我认为你可以重构你的查询并删除子查询.删除子查询并将其结果作为参数传递将允许您使用DQL,因此支持更多类型的数据库.
归档时间: |
|
查看次数: |
1280 次 |
最近记录: |