2017-08-04 107 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