Symfony where条件下的ORM计数数组集合
使用Symfony where条件下的ORM计数数组集合,symfony,orm,doctrine-orm,arraycollection,Symfony,Orm,Doctrine Orm,Arraycollection,使用Symfony2.8和原则2.5,我想在原则ORM查询中过滤arraycollection正好包含3个元素的所有数据集 $em = $this->getDoctrine()->getManager(); $query = $em->getRepository("AppBundle:EduStructItem") ->createQueryBuilder('e') ->addSelect('COUNT(e.preconditions) AS HIDDEN num
Symfony2.8
和原则2.5
,我想在原则ORM查询中过滤arraycollection正好包含3个元素的所有数据集
$em = $this->getDoctrine()->getManager();
$query = $em->getRepository("AppBundle:EduStructItem")
->createQueryBuilder('e')
->addSelect('COUNT(e.preconditions) AS HIDDEN numberpre')
->having('numberpre = 3')
->getQuery();
$res = $query->getResult();
dump($res);
foreach ($res as $entity){
print "title:".$entity->getTitle()."<br>";
dump($entity->getPreconditions()->toArray());
}
下面是一个测试实体:
<?php
// src/AppBundle/Entity/EduStructItem.php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Table(name="test_edustructitemcollection")
*/
class EduStructItem
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
* @Assert\NotBlank()
* @ORM\Column(type="string", length=255, nullable=false)
*/
private $title;
/**
* Preconditions are EduStructItems referencing to an EduStructItem.
* For a single EduStructItem its empty (which have no subelements).
* A join table holds the references of a main EduStructItem to its sub-EduStructItems (preconditions)
*
* @ORM\ManyToMany(targetEntity="EduStructItem",indexBy="id", cascade={"persist"})
* @ORM\JoinTable(name="test_edustructitem_preconditioncollection",
* joinColumns={@ORM\JoinColumn(name="edustructitem_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="edustructitem_precondition_id", referencedColumnName="id")}
* )
*/
public $preconditions;
public function __construct()
{
$this->preconditions = new ArrayCollection();
}
public function getTitle()
{
return $this->title;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getPreconditions()
{
return $this->preconditions;
}
public function addPrecondition(\AppBundle\Entity\EduStructItem $precondition)
{
$this->preconditions->add($precondition);
}
public function removePrecondition(\AppBundle\Entity\EduStructItem $precondition)
{
$this->preconditions->removeElement($precondition);
}
}
?>
然后再次获取错误:
[语义错误]第0行,第18列“前提条件”附近):错误:无效的PathExpression。应为StateFieldPathExpression或SingleValuedAssociationField。Wenn我在HIDDEN I get之前写入别名:[语义错误]第0行,第53列靠近'FROM AppBundle\Entity\EduStructItem':错误:未定义类'FROM'。认为它是一个自我反映的关系,只有一个实体,但有两个表。正如您在我的实体的注释中所看到的,自关系保存在test_educstructItem_premissioncollection-表中,该表是由于注释而由条令生成的
我尝试了您的最新解决方案:
$em = $this->getDoctrine()->getManager();
$query = $em->getRepository("AppBundle:EduStructItem")
->createQueryBuilder('e')
->addSelect('COUNT(e.preconditions) AS HIDDEN countpre')
->join('e.preconditions', 'precondition', Join::WITH)
->having('countpre = 1')
->getQuery();
$qb = $em->getRepository("AppBundle:EduStructItem")
->createQueryBuilder('item');
$qb->addSelect('COUNT(precondition.id) AS countpre HIDDEN ')
->join('item.preconditions', 'precondition', Join::WITH)
->having('countpre = 1');
当我隐藏countpre之前,我总是会出现以下错误:
[语义错误]第0行,第56列,靠近“来自AppBundle\Entity\EduStructItem”:错误:未定义类“来自”
但当我把countpre藏起来之后:
$qb = $em->getRepository("AppBundle:EduStructItem")
->createQueryBuilder('item');
$qb->addSelect('COUNT(precondition.id) AS HIDDEN countpre')
->join('item.preconditions', 'precondition', Join::WITH)
->having('countpre = 1');
我得到一个错误:
从t0上的test_EducturItemCollection t0_内部联接测试_EducturItem_预条件集合t2_id为sclr=1’执行“选择t0_.id为id_0,t0_.title为title_1,计数(t1_.id)为sclr_2”时发生异常
SQLSTATE[42S22207]:[Microsoft][SQL Server的ODBC驱动程序11][SQL Server]Ungültiger Spaltenname“sclr_2”
500内部服务器错误-DBALException
1链接异常:SqlSrveException»
请考虑只有一个实体有自给性,有两个表:
USE [easylearndev4_rsc]
GO
/****** Object: Table [dbo].[test_edustructitemcollection] Script Date: 14.12.2015 09:31:55 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[test_edustructitemcollection](
[id] [int] IDENTITY(1,1) NOT NULL,
[title] [nvarchar](255) NOT NULL,
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
及
最后我自己找到了一个解决办法:
$em = $this->getDoctrine()->getManager();
$qb = $em->getRepository("AppBundle:EduStructItem")
->createQueryBuilder('e');
$qb->join('e.preconditions', 'p', Join::WITH)
->groupBy('e.id, e.title')
->having('count(p.id) = 1');
但我对此不太满意,因为arraycollection已经是聚合数据了。为什么我要再次加入、计数和分组呢!
这不可能是教义的理念!
有人知道更好的解决方案吗
$qb = $this->getDoctrine()->getManager()->getRepository"MyBundle:Groups")
->createQueryBuilder('g')
->addSelect('COUNT(g.members) AS count HIDDEN')
->having('count = 3')
->orderBy('count', 'DESC')
;
编辑
在您更新了您的问题之后,应该很清楚上述解决方案将不起作用,因为您的情况是您需要计算关系对象,而不是单个字段
$qb = $em->getRepository("AppBundle:EduStructItem") //Selfreferencing ManyToMany
->createQueryBuilder('item');
$qb->addSelect("COUNT(precondition.id) AS count HIDDEN")
->join('item.preconditions', 'precondition', Join::WITH)
->having('count = 3')
->orderBy('count');
试试这个:
$qb = $this->getDoctrine()->getManager()->getRepository("MyBundle:Groups")
->createQueryBuilder('g')
->having('count(g.members) = 3')
->orderBy('g.members', 'DESC')
;
这不起作用:[语义错误]第0行,mebers附近的第109列]:错误:无效的PathExpression。应为StateFieldPathExpression或SingleValuedAssociationField。arraycollection不接受为count()的参数!我们可以看看你的实体和更具体的映射吗?我编辑了我的帖子并添加了一个示例代码。问题是我无法将count()应用于arraycollection—我想知道为什么您可以!这不起作用:$qb->addSelect('COUNT('g.members')AS COUNT HIDDEN')由于嵌套引号而出现语法错误。我将其更改为$qb->addSelect(“COUNT('g.members')AS COUNT HIDDEN”),但它仍然会导致以下错误消息:[语法错误]第0行,第101列:错误:预期文字,使用更新的代码获得“COUNT”,我得到错误:[语义错误]第0行,列101靠近“count=3”:错误:“count”未定义。在where条件下,似乎无法访问隐藏值。在where条件下,存在on
where
时,它是具有
。我已经在许多项目中使用了这段代码。也许你的背景有所不同。请考虑更新的问题文本。现在有一个例子。最后我自己找到了一个解决办法,但我不太满意。请检查更新的问题。
$qb = $em->getRepository("AppBundle:EduStructItem") //Selfreferencing ManyToMany
->createQueryBuilder('item');
$qb->addSelect("COUNT(precondition.id) AS count HIDDEN")
->join('item.preconditions', 'precondition', Join::WITH)
->having('count = 3')
->orderBy('count');
$qb = $this->getDoctrine()->getManager()->getRepository("MyBundle:Groups")
->createQueryBuilder('g')
->having('count(g.members) = 3')
->orderBy('g.members', 'DESC')
;