2017-08-04 65 views
2

我有两个实体通过与连接表关联的一对多单向连接。学说查询一对多一对多连接表中的一个实体

use Doctrine\ORM\Mapping as ORM; 

/** 
* @Entity(repositoryClass="FooRepository") 
*/ 
class Foo 
{ 
    /** 
    * @var Collection 
    * @ORM\ManyToMany(targetEntity="Bar") 
    * @ORM\JoinTable(
    *  name="foo_bar", 
    *  inverseJoinColumns={@ORM\JoinColumn(unique=true)} 
    *) 
    */ 
    private $bars; 

    /** 
    * @var int 
    * @ORM\Column(type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    // [...] 
} 
/** 
* @Entity(repositoryClass="BarRepository") 
*/ 
class Bar 
{ 
    /** 
    * @var int 
    * @ORM\Column(type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    // [...] 
} 

我想创建一个方法将使用一个Foo ID和酒吧id,这将返回一个或空Bar对象我BarRepository类。

其实我的课是这样的:

use Doctrine\ORM\EntityRepository; 

class BarRepository extends EntityRepository 
{ 
    /** 
    * Finds a single bar. 
    * @param int $fooId The foo identifier. 
    * @param int $barId The bar identifier. 
    * @return Bar|null 
    */ 
    public function findOneByFoo($fooId, $barId) 
    { 
     $qb = $this->createQueryBuilder('b'); 
     $qb->innerJoin('Foo', 'f', Expr\Join::WITH, 'f.id = :fooId') 
     ->where('b.id = :barId') 
     ->setParameter('fooId', $fooId) 
     ->setParameter('barId', $barId) 
     ->getQuery()->getOneOrNullResult(); 
    } 
} 

但这总是返回就算了吧ID没有关联到Foo对象酒吧对象。

回答

0

好的,感谢staskrak,我重写了这个“查询”,并且它工作正常。 FooBar实体是相同的。 我保持查询的相同基础,但在Foo->bars属性和Bar实体之间添加了一个内部联接。

use Doctrine\ORM\EntityRepository; 

class BarRepository extends EntityRepository 
{ 
    public function findOneByFoo($fooId, $barId) 
    { 
     $parameters = [ 
      ':fooId' => $fooId, 
      ':barId' => $barId 
     ]; 
     $qb = $this->createQueryBuilder('b'); 
     return $qb 
      ->innerJoin('Foo', 'f', 'WITH', 'f.id = :fooId') 
      // below, the added inner join 
      // it makes the link between the Foo->bars property and the Bar entity 
      ->innerJoin('f.bars', 'fb', 'WITH', 'b.id = fb.id') 
      ->where('b.id = :barId') 
      ->setParameters($parameters) 
      ->getQuery() 
      ->getOneOrNullResult(); 
    } 
} 
1
  1. 首先!这不是必需的,但我建议你总是在注释中编写 完整映射。

    让我们看看你的实体。我们可以对您的下一个断言 一对多:

    One Foo对象可以有很多Bar对象,但是每个Bar对象只能引用一个而不会引用更多的Foo对象 。 例如,一个人可以拥有很多信用卡,但每张卡只能属于一个人。

因此,我们可以写下:

/** 
* @Entity(repositoryClass="FooRepository") 
*/ 
class Foo 
{ 
    /** 
     * Unidirectional One-To-Many 
     * One Foo has many Bar, however Bar has only one Foo 
     * 
     * @ORM\ManyToMany(targetEntity="Bar") 
     * @ORM\JoinTable(
     *  name="foo_bar_table", 
     *  joinColumns={@JoinColumn(name="foo_id", referencedColumnName="id")}, 
     *  inverseJoinColumns={@JoinColumn(name="bar_id", referencedColumnName="id", unique=true) 
     */ 
     private $bars; 

    /** 
     * Foo constructor 
     */ 
     public function __construct() 
     { 
     $this->bars = new \Doctrine\Common\Collections\ArrayCollection(); 
     } 
  • 当然,你将永远与你输入ID酒吧对象。 为什么?让我们看看你们的关系(表格)。 富 - 这是一个表,它有字段ID。
    酒吧 - 这是一个表,它有字段ID。 foo_bar_table - 此表具有foo_id,bar_id。

    当您进行连接时 - 您只需向另一个表中添加另一个连接。 这些表彼此之间没有关联。所以你想要 酒吧对象 - 你明白了。
    您需要从Bar存储库获取Bar对象。这将是 更好。

  • +0

    谢谢你staskrak。但是使用BarRepository获取Bar对象更合乎逻辑吗? – Calcimicium

    +0

    当然你是正确的Calcimicium。这只是一个错字。我们需要从BarRepository中获取Bar对象。 我已经改正了我的帖子。也谢谢你。 – staskrak