使用Symfony2.8
with Doctrine 2.5
,我想在Doctrine 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()."
"; dump($entity->getPreconditions()->toArray()); }
preconditions
是一个包含前提条件集合的arraycollection.
最后,我希望得到所有结果正好有3个前提条件.另外,也可以通过arraycollection中的值的数量来排序(类似order by Count(e.preconditions)
).
由于使用了另一个捆绑包,我将原则从2.5.2降级到2.5.0.我不认为这是我的问题的原因,但为了完整起见,这是我的作曲家秀的教义部分:
data-dog/pager-bundle v0.2.4 Paginator bundle for symfony2 and doctrine orm, allows customization with filters and sorters doctrine/annotations v1.2.7 Docblock Annotations Parser doctrine/cache v1.5.2 Caching library offering an object-oriented API for many cache backends doctrine/collections v1.3.0 Collections Abstraction library doctrine/common v2.5.2 Common Library for Doctrine projects doctrine/data-fixtures v1.1.1 Data Fixtures for all Doctrine Object Managers doctrine/dbal v2.5.2 Database Abstraction Layer doctrine/doctrine-bundle 1.6.1 Symfony DoctrineBundle doctrine/doctrine-cache-bundle 1.2.2 Symfony Bundle for Doctrine Cache doctrine/doctrine-fixtures-bundle 2.3.0 Symfony DoctrineFixturesBundle doctrine/doctrine-migrations-bundle 1.1.1 Symfony DoctrineMigrationsBundle doctrine/inflector v1.1.0 Common String Manipulations with regard to casing and singular/plural rules. doctrine/instantiator 1.0.5 A small, lightweight utility to instantiate objects in PHP without invoking their constructors doctrine/lexer v1.0.1 Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers. doctrine/migrations v1.1.0 Database Schema migrations using Doctrine DBAL doctrine/orm v2.5.0 Object-Relational-Mapper for PHP
这是一个测试实体:
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行靠近'preconditions)':错误:无效的PathExpression.期望StateFieldPathExpression或SingleValuedAssociationField.
现在我尝试了你的新解决方案:
$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();
并再次出现错误:[语义错误]第0行,第18行附近'preconditions)':错误:无效的PathExpression.期望StateFieldPathExpression或SingleValuedAssociationField.我在HIDDEN之前写了别名我也得到了:[语义错误]第0行,第53页'FROM AppBundle\Entity\EduStructItem'附近:错误:未定义类'FROM'.考虑它是一个自我反思的关系,只有一个实体,但有两个表.正如您在我的实体的注释中所看到的,自我关系被保存在test_edustructitem_preconditioncollection中 - 由于注释而由学说生成的表.
我试过你最新的解决方案:
$qb = $em->getRepository("AppBundle:EduStructItem") ->createQueryBuilder('item'); $qb->addSelect('COUNT(precondition.id) AS countpre HIDDEN ') ->join('item.preconditions', 'precondition', Join::WITH) ->having('countpre = 1');
当我在HIDDEN之前有countpre我总是得到这个错误:[语义错误]第0行,第56页'FROM AppBundle\Entity\EduStructItem'附近:错误:未定义类'FROM'.
但是当我在HIDDEN之后放了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');
我收到错误:执行'SELECT t0_.id时发生异常AS id_0,t0_.title AS title_1,COUNT(t1_.id)AS sclr_2 FROM test_edustructitemcollection t0_ INNER JOIN test_edustructitem_preconditioncollection t2_ ON t0_.id = t2_.edustructitem_id INNER JOIN test_edustructitemcollection t1_ ON t1_.id = t2_.edustructitem_precondition_id具有sclr_2 = 1':
SQLSTATE [42S22,207]:[Microsoft] [SQL Server的ODBC驱动程序11] [SQL Server]UngültigerSpaltenname'sclr_2'.
500内部服务器错误 - DBALException
1链接异常:SQLSrvException»
请考虑只有一个具有自引用的实体,并且有这两个表:
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
和
USE [easylearndev4_rsc] GO /****** Object: Table [dbo].[test_edustructitem_preconditioncollection] Script Date: 14.12.2015 09:32:21 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO REATE TABLE [dbo].[test_edustructitem_preconditioncollection]( [edustructitem_id] [int] NOT NULL, [edustructitem_precondition_id] [int] NOT NULL, PRIMARY KEY CLUSTERED ( [edustructitem_id] ASC, [edustructitem_precondition_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 ALTER TABLE [dbo].[test_edustructitem_preconditioncollection] WITH CHECK ADD CONSTRAINT [FK_34E716A81B7A6CEB] FOREIGN KEY([edustructitem_precondition_id]) REFERENCES [dbo].[test_edustructitemcollection] ([id]) GO ALTER TABLE [dbo].[test_edustructitem_preconditioncollection] CHECK CONSTRAINT [FK_34E716A81B7A6CEB] GO ALTER TABLE [dbo].[test_edustructitem_preconditioncollection] WITH CHECK ADD CONSTRAINT [FK_34E716A85D864668] FOREIGN KEY([edustructitem_id]) REFERENCES [dbo].[test_edustructitemcollection] ([id]) GO ALTER TABLE [dbo].[test_edustructitem_preconditioncollection] CHECK CONSTRAINT [FK_34E716A85D864668] 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');
但我对此并不满意,因为数组收集已经是聚合数据,我为什么要加入,再次计数和分组!这不是主义的想法!有谁知道更好的解决方案?