【问题标题】:Doctrine - Get items based on the count of a many to manyDoctrine - 根据多对多的计数获取项目
【发布时间】:2014-05-31 00:53:27
【问题描述】:

我有以下表格,用户、项目和图像。

用户与项目和图像具有一对多的关系。每个项目和图像都归一个用户所有。

项目与图像具有多对多关系。所以每个Project可以有很多Image,一个Image可以出现在很多Project中。

我想为未包含在任何项目中的特定用户编写一个 DQL 查询来获取所有图像。这我可以用 SQL 编写。

用 SQL 编写是最好的方法吗?

或者我应该使用 DQL 来执行此操作吗?

我曾尝试编写 DQL,但它的工作很辛苦!

编辑

在我的图像仓库中,我现在正在这样做

$qb = $this->createQueryBuilder("i");

$qb->select("i")
    ->from('MyBundleName:User','u')
    ->innerJoin('u.images', 'user_images')
    ->where('IDENTITY(u.id) = :user_id')
    ->andWhere('NOT EXISTS (
        SELECT p
        FROM MyBundleName:Project p
        WHERE user_images MEMBER of p.images
    )')
->setParameter('user_id', $user_id);

我已经用: 替换了我的课程的/ 语法,因为它们在使用/ 时失败了

我仍然收到此错误;

[语义错误] 第 0 行,第 131 列靠近 'id) = :user_id':错误: 无效的路径表达式。必须是 SingleValuedAssociationField。

函数createQueryBuilder 需要一个别名,我将它传递给"i" - 对吗?

然后我在调用select时再次给它"i"

如果我删除 innerJoin 则它可以工作,但结果是错误的。它返回所有图像,即使它们确实存在于项目中。

【问题讨论】:

    标签: sql symfony doctrine-orm


    【解决方案1】:

    我不能说在 DQL 中会有多难,但我可以告诉你,在 SQL 中这听起来很简单:

    SELECT I.*
    FROM IMAGES I
    INNER JOIN USERS U ON (I.USER_ID = U.USER_ID)
    WHERE NOT EXISTS (
        SELECT *
        FROM   PROJECTS P, PROJECT_IMAGES PI
        WHERE  P.USER_ID = U.USER_ID
        AND    PI.PROJECT_ID = P.PROJECT_ID
        AND    I.IMAGE_ID = PI.IMAGE_ID
    )
    

    用户拥有的图像不存在于该用户拥有的任何项目中。

    【讨论】:

      【解决方案2】:

      我不知道您的实体是什么样的,但考虑到这样的关系应该可以工作。关键是将NOT EXISTSMEMBER OF 结合起来(您要确保对于所有返回的图像,不存在该图像所属的项目)。

      $qb->select("i")
          ->from('MyBundle\Entity\User','u')
          ->innerJoin('u.images','i')
          ->where('IDENTITY(u) = :user_id')
          ->andWhere('NOT EXISTS (
              SELECT p
              FROM MyBundle\Entity\Project p 
              WHERE i MEMBER of p.images
            )')
          ->setParameter('user_id', $user_id);
      

      【讨论】:

      • 这看起来不错,但我得到了这个[Semantical Error] line 0, col 99 near 'u) = :user_i': Error: Invalid PathExpression. Must be a SingleValuedAssociationField.
      • 尝试用u.id替换IDENTITY(u)
      • 试过了,结果一样。我认为我有更大的问题,因为该项目正在运行 2.1 版
      • 如果我将它放在现有实体的 Repo 类中,我会将它放在哪个类中?看看你的例子,我猜是 Image Repo?
      • @JakeN 因为查询返回Image 实体,这就是我将其放入的存储库,但如果您在from 中使用完整的类名,那么我认为这并不重要跨度>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-06
      • 1970-01-01
      • 2022-01-17
      • 2016-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多