原则:使用组合外键查询实体


Doctrine: querying entities with composite foreign key

设置

我有三个实体:

  • WordList
  • WordInWordlist

WordList与WordList有一个onetmany关系。wordlist与Definition有一多关系


我在尝试什么

我正在尝试查询所有的定义行,其中word_id = ?和wordlist_id = ?

在标准SQL中,我会这样写:

SELECT * FROM definition WHERE word_wordlist_word_id = ? AND word_wordlist_wordlist_id = ?;

代码片段

WordInWordlist实体的适用部分是blow:

class WordInWordlist
{   
    /**
     *
     * @ORM'OneToMany(targetEntity="Definition", mappedBy="wordInWordlist")
     * @ORM'JoinColumns({
     *   @ORM'JoinColumn(name="word_id", referencedColumnName="word_wordlist_word_id"),
     *   @ORM'JoinColumn(name="wordlist_id", referencedColumnName="word_wordlist_wordlist_id")
     * })
     * @Expose()
     **/
    protected $definitions;

    /**
     * @ORM'Id
     * @ORM'ManyToOne(targetEntity="Wordlist", inversedBy="wordInWordlist")
     * @ORM'JoinColumn(name="wordlist_id", referencedColumnName="id")
     **/
    protected $wordlist;

定义实体的适用部分如下:

class Definition
{
    /**
     * @ORM'ManyToOne(targetEntity="WordInWordlist", inversedBy="definitions")
     * @ORM'JoinColumns({
     *   @ORM'JoinColumn(name="word_wordlist_word_id", referencedColumnName="word_id"),
     *   @ORM'JoinColumn(name="word_wordlist_wordlist_id", referencedColumnName="wordlist_id")
     * })
     **/
    protected $wordInWordlist;

我的尝试<标题> 1
public function getDefinitions($wordlist_id, $word_id)
{
    $query = $this->createQueryBuilder('d')
      ->where('d.word_wordlist_word_id = :word_id')
      ->andWhere('d.word_wordlist_wordlist_id = :wordlist_id')
      ->setParameter('word_wordlist_word_id', $word_id)
      ->setParameter('word_wordlist_wordlist_id', $wordlist_id)
      ->getQuery();
    return $query->getResult();
}
结果:

PHP Fatal error:  Uncaught Doctrine'ORM'Query'QueryException: SELECT d FROM Spellingbee'Business'Entity'Definition d WHERE d.word_wordlist_word_id = :word_id AND d.word_wordlist_wordlist_id = :wordlist_id in /home/dporter/projects/list_management/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php:41 Stack trace:
#0 /home/dporter/projects/list_management/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php(483): Doctrine'ORM'Query'QueryException::dqlError('SELECT d FROM S...')
#1 /home/dporter/projects/list_management/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php(758): Doctrine'ORM'Query'Parser->semanticalError('line 0, col 63 ...', Array)
#2 /home/dporter/projects/list_management/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php(279): Doctrine'ORM'Query'Parser->processDeferredPathExpressions(Object(Doctrine'ORM'Query'AST'SelectStatement))
#3 /home/dporter/projects/list_management/vendor/doctrine/orm/lib/Doctrine/ORM/Query/Parser.php(351): Doctrine'ORM'Query'Parser->getAST()
#4 /home/dporter/projects/lis in /home/dporter/projects/list_management/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php on line 63
<标题> 2 h1>

结果:

Fatal error: Uncaught Doctrine'ORM'Query'QueryException: A single-valued association path expression to an entity with a composite primary key is not supported. Explicitly name the components of the composite primary key in the query. in /home/dporter/projects/list_management/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php:235 Stack trace:
#0 /home/dporter/projects/list_management/vendor/doctrine/orm/lib/Doctrine/ORM/Query/SqlWalker.php(676): Doctrine'ORM'Query'QueryException::associationPathCompositeKeyNotSupported()
#1 /home/dporter/projects/list_management/vendor/doctrine/orm/lib/Doctrine/ORM/Query/AST/PathExpression.php(79): Doctrine'ORM'Query'SqlWalker->walkPathExpression(Object(Doctrine'ORM'Query'AST'PathExpression))
#2 /home/dporter/projects/list_management/vendor/doctrine/orm/lib/Doctrine/ORM/Query/SqlWalker.php(2295): Doctrine'ORM'Query'AST'PathExpression->dispatch(Object(Doctrine'ORM'Query'SqlWalker))
#3 /home/dporter/projects/list_management/vendor/doctrine/orm/lib/Doctrine/ORM/Query/SqlWalker.php in /home/dporter/projects/list_management/vendor/doctrine/orm/lib/Doctrine/ORM/Query/QueryException.php on line 235

我如何创建一个学说查询来获得我在"我正在尝试什么"一节中概述的结果。

谢谢

你尝试过这种方式,你的方法的签名是一个数组吗?

public function getDefinitions(array $ids)
{
 $query = $this->createQueryBuilder('d')
  ->where('d.wordInWordlist IN (:wordlist_id)')
  ->setParameter('wordlist_id', $ids)
  ->getQuery();
 return $query->getResult();
}

希望对你有帮助

不幸的是,Doctrine不允许我尝试的查询(这似乎很基本)。使用DQL或查询构建器进行此操作的唯一方法是在逆表上连接并按适当的字段进行过滤。

所以这是我的最终结果:

public function getDefinitions($wordlist_id, $word_id)
{
    $query = $this->createQueryBuilder('d')
      ->innerJoin('d.wordInWordlist', 'w')
      ->where('w.wordlist = :wordlist')
      ->andWhere('w.word = :word')
      ->setParameters(array(
        'word' => $word_id,
        'wordlist' => $wordlist_id
        )
      )
      ->getQuery();
    return $query->getResult();
}