symfony2 学说加入
Posted
技术标签:
【中文标题】symfony2 学说加入【英文标题】:symfony2 doctrine join 【发布时间】:2012-04-04 19:37:10 【问题描述】:好的,所以我有一个查询,我已经研究并研究了如何让它工作,而我这辈子做不到!...也许我只是做错了,而且我得到的信息很少找到了..
我有一个名为 timeclock setup.. 的表,其中有一个字段:noteBy_id,它是记录所属用户的 id...
我现在需要做的是系统中事物的管理方面。我预计会有超过 1 家公司使用这个时钟系统,因此我需要根据公司 ID 过滤结果。在用户表,我有一个名为parentcompany_id
的字段
所以,让我们看看我是否可以用语言表达我需要做的事情..
我需要从时钟中选择 * 并离开加入 user.parentcompany_id where timeclock.daydate
开始是:`date('Y-m-d 00:00:00');
我已经设置了这个查询:
$em = $this->getDoctrine()->getEntityManager();
$start = date('Y-m-d 00:00:00');
$qb = $em->getRepository('EcsCrmBundle:TimeClock');
$qb = $qb->createQueryBuilder('t');
$query = $qb->select('t, u.parentcompany_id')
->from('timeclock', 't')
->leftJoin('Ecs\AgentManagerBundle\Entity\User', 'u', 'ON' 'u.id = t.noteBy_id AND u.parentcompany_id = :pid')
->where('t.daydate < :start')
->andWhere("t.noteBy_id != ''")
->setParameter('start', $start)
->setParameter('pid', $user->getParentcompany())
->getQuery();
$entities = $query->getArrayResult();
我看了又看,找不到解决我得到的错误的方法:
An exception has been thrown during the rendering of a template ("[Semantical Error] line 0, col 112 near 'u ON u.id = t.noteBy_id': Error: Identification Variable Ecs\AgentManagerBundle\Entity\User used in join path expression but was not defined before.") in EcsCrmBundle:TimeClock:manager.html.twig at line 5.
得到输出的查询是:
SELECT t, u.parentcompany_id FROM Ecs\CrmBundle\Entity\TimeClock t LEFT JOIN Ecs\AgentManagerBundle\Entity\User u ON u.id = t.noteBy_id AND u.parentcompany_id = :pid, timeclock t LEFT JOIN Ecs\AgentManagerBundle\Entity\User u ON u.id = t.noteBy_id AND u.parentcompany_id = :pid WHERE t.daydate < :start AND t.noteBy_id != ''
在正常情况下可以完美运行...但在这种情况下,它只是不...有什么想法吗?
【问题讨论】:
我刚刚注意到,上面的代码给了我 2 个 LEFT JOINS 而不是 1 个...所以谁知道真正的问题在哪里... 在以下人员的帮助下:***.com/questions/9399355/… 我解决了这个问题..... 【参考方案1】:我最近不得不这样做.. 我猜你的 noteBy 是用户表中的 ManyToOne 并且你想让它过滤当前管理员公司的结果登录你的系统..
因此,为这样的任务调整我必须自己编写的连接很容易。我个人喜欢使用 QueryBuilder,所以这将在查询生成器中完成..
您查询中的第一个错误是->from('timeclock', 't')
行。因为您之前使用 $qb = $em->getRepository('EcsCrmBundle:TimeClock'); $qb = $qb->createQueryBuilder('t');
创建了对象,所以不需要在查询构建器中使用 from
,因为它会为您生成。
下一个问题是 leftJoin,当我向您展示工作版本时,我会解释原因。
最后一个问题,阻止它按你的意愿工作 - 是缺少andWhere
子句。那么,让我们来看看一个有效的查询。
$query = $qb->select('t, u')
->leftJoin('t.noteBy', 'u', 'WITH', 'u.id = t.noteBy')
->where('t.daydate < :start')
->andWhere('u.parentcompany = :pid')
->setParameter('start', $start)
->setParameter('pid', $user->getParentcompany())
->getQuery();
因为我们已经使用$qb = $qb->createQueryBuilder('t')
创建了对象,所以我们只需选择t
和u
对于连接,我们通过noteBy
列连接时钟表,这是用户表中的用户ID。因此,第一个参数是“来自”别名。因此,由于我们使用 t 为时钟表起别名,我们使用 t.noteBy
。 leftjoin 中的下一个参数是第二个表的别名,在这种情况下是u
,但可以是任何东西。无论如何,leftJoin 的第三个参数 - 是你加入它的方式。@ 987654332@ 或ON
将在这里工作。第四个参数是您希望它拥有的匹配项。在这种情况下u.id must equal t.noteBy
您会看到我删除了andWhere
之一,我这样做是因为使用结构正确的查询您不需要它。但是,我确实为 u.parentcompany
添加了 andWhere
,因为毕竟这是您要过滤的内容,您应该将其放在 WHERE 中,而不是作为连接本身的匹配项。
这方面的文档非常有限,我也花了一段时间才弄清楚。毫无疑问,你和我一样,是通过手工编写查询来使用学说的。因此,由于您似乎刚刚开始使用 Symfony(我自己也是现在大约 2 个月),您仍然处于手动编码的心态。但随着时间的推移,您将开始了解 DQL 的生活方式。试试这个查询,看看会发生什么。
【讨论】:
【参考方案2】:好的,首先您需要将实体Timeclock
与Company
关联起来。每当您想连接Doctrine
中的两个实体时,它们都需要通过某个属性(即表列)关联。
我认为此查询中不需要 User
实体,因为所有信息都可通过 Company
实体获得,并且您没有根据任何用户属性过滤结果。
您想要的查询应该看起来像这样(或多或少)。我冒昧地从实体属性中删除了_id
后缀,因为它们往往会掩盖真正发生的事情。 ;)
$query = $this->getEntityManager()->createQuery("SELECT t, c.id FROM EcsCrmBundle:TimeClock t JOIN t.company c WHERE c.id = :pid AND t.daydate < :start AND t.noteBy != ''");
$query->setParameter('start', $start);
$query->setParameter('pid', $user->getParentcompany());
return $query->getArrayResult();
另外,我做了inner-join
(JOIN
),因为我认为没有它的陪伴就不可能有时钟,但如果更适合您,请随时将其更改为 LEFT JOIN
。
这是您想要达到的目标吗?
【讨论】:
公司实体与用户实体一样位于另一个 Bundle 中。无论如何,对我而言,您的解决方案的问题是 TimeClock 表引用了用户的 ID,因此是用户表里面有父公司而不是时钟表。所以我必须使用用户表来过滤当前登录的经理公司的结果......以上是关于symfony2 学说加入的主要内容,如果未能解决你的问题,请参考以下文章