2016-01-05 59 views
2

請看下圖: enter image description here主義類表繼承 - 預先加載子類引用

User有許多BlogPost的,一個Event是與Venue屬性的類型BlogPost

我有以下實體類:

** 
* @ORM\Entity() 
* @ORM\Table(name="User") 
*/ 
class User { 
    ... 
    /** 
    * @ORM\OneToMany(targetEntity="BlogPost",mappedBy="User") 
    * @ORM\JoinColumn(...) 
    */ 
    protected $BlogPosts; 
    ... 
} 

/** 
* @ORM\Entity() 
* @ORM\Table(name="BlogPost") 
* @ORM\InheritanceType("JOINED") 
* @ORM\DiscriminatorColumn(...) 
* @ORM\DiscriminatorMap({...}) 
* ... 
*/ 
class BlogPost { 
    ... 
    /** 
    * @ORM\ManyToOne(targetEntity="User",inversedBy="BlogPosts") 
    * @ORM\JoinColumn(...) 
    */ 
    protected $User 
    ... 
} 

/** 
* @ORM\Entity() 
* @ORM\Table(name="Event") 
*/ 
class Event extends BlogPost { 
    ... 
    /** 
    * @ORM\ManyToOne(targetEntity="Venue") 
    * @ORM\JoinColumn(...) 
    */ 
    protected $Venue; 
    ... 
} 

/** 
* @ORM\Entity() 
* @ORM\Table(name="Venue") 
*/ 
class Venue { 
    ... 
} 

現在我想建立一個查詢,獲取給定用戶的活動和熱切加載活動場地。我得到的最接近是:

$qb = $em->createQueryBuilder(); 
$qb 
    ->select('User,'BlogPost,Venue') 
    ->from('User','User') 
    ->join('User.BlogPosts','BlogPost','WITH','BlogPost INSTANCE OF :Event') 
    ->join('BlogPost.Venue','Venue') 
    ->setParameter('Event',$em->getClassMetadata('Event')); 

這給了我一個相當可預測的錯誤:

Error: Class BlogPost has no association named Venue 

刪除引用Venue我會得到所有用戶Event很好,沒有問題,但隨後的我將不得不依靠延遲加載來獲得Event的其餘屬性。

我已經看到了我映射EventsUser建議:

class User { 
    ... 
    /** 
    * @ORM\OneToMany(targetEntity="BlogPost",mappedBy="User") 
    * @ORM\JoinColumn(name="UserID", referenceColumnName="UserID") 
    */ 
    protected $BlogPosts; 

    /** 
    * @ORM\OneToMany(targetEntity="Event",mappedBy="User") 
    * @ORM\JoinColumn(name="UserID", referenceColumnName="UserID") 
    */ 
    protected $Events; 
    ... 
} 

嘗試此,所產生的嘗試做一些事情,如SQL:

SELECT * FROM User 
JOIN Event ON User.id = Event.user_id 
JOIN BlogPost ON BlogPost.id = Event.blog_post_id 

user_id在列BlogPost而不是Event並因此出現錯誤:

Invalid column name 'user_id' 

我應該如何映射類表繼承的引用? 有沒有一種方法來實現我所描述的急切加載?

我知道我從類中刪除了大量的細節,它們的映射和生成的SQL。如果某些細節能夠幫助我們瞭解這一點,請留言。

編輯

這不同於Single Table Inheritance (STI) with a ManyToOne relationship作爲其類表繼承,而不是單表繼承。此外,我對子類的屬性細節感興趣,想象一下,如果在該示例中,Video有其他參考。

+1

可能重複[Single Table Inheritance(STI)with ManyToOne relationship](http://stackoverflow.com/questions/34458198/single-table-inheritance-sti-with-a-manytoone-relationship) – Wilt

+0

有很多類似的問題都可以在stackoverflow上找到。 – Wilt

+0

編輯來解釋這兩個問題之間的差異 –

回答

0

我發現了一種做我想做的事的方式,但我確信必須有更好的方法。

先寫一個本地查詢:

$sql =<<<SQL 
SELECT * FROM User user 
JOIN BlogPost blog_post ON user.id = blog_post.UserID 
JOIN Event event ON blog_post.id = event.BlogPostID 
JOIN Venue venue ON event.VenueID = venue.id 
WHERE user.id = ? 
SQL; 

這可以直接與我通過$em->getConnection()->prepare()運行或更好的使用ResultSetMapping然後通過$em->createNativeQuery($sql,$rsm)

$rsm = new \Doctrine\ORM\Query\ResultSetMappingBuilder($em); 
$rsm->addRootEntityFromClassMetadata('User','user'); 
$rsm->addIndexBy('user','id'); 
$rsm->addJoinedEntityResult('event','event','user','BlogPosts'); 
$rsm->addJoinedEntityResult('venue','venue','event','Venue'); 
$rsm->addFieldResult(); // add all of the fields you are interested in 

$query = $this->get_manager()->createNativeQuery($sql,$rsm); 
$query->setParameter(1, $user_id); 

return $query->getResult($hydration_mode); 

這似乎是一個恥辱,這可以」通過QueryBuilder完成,但據我所知,這是實現這一目標的唯一方法。我很樂意被證明。