簡體   English   中英

原則2:獲取直接映射到實體中的一對多關系的計數

[英]Doctrine2: get count of one to many relation directly mapped in entity

我正在使用doctrine2和symfony3.1

我有一個Movie列表,人們可以使用一對多關系購買Movie Ticket

我要在儀表板上顯示電影列表,以及每張電影的購票數量

通過這樣做我得到了我想要的數據

    $manager = $this->getDoctrine()->getManager();
    $builder = $manager->createQueryBuilder();

    $results = $builder
        ->select('m')
        ->from('AppBundle:Movie', 'm')
        ->addSelect($builder->expr()->count('t'))
        ->leftJoin('m.tickets', 't')
        ->groupBy('m.id')
        ->getQuery()
        ->getResult()
    ;

它可以制作100部電影,其中1部要求:

SELECT
       e0_.title AS title_0,
       e0_.is_published AS is_published_1,
       e0_.description AS description_2,
       e0_.author AS author_3,
       e0_.director AS director_4,
       e0_.artist_list AS artist_list_5,
       e0_.tags_list AS tags_list_6,
       e0_.creation_time AS creation_time_7,
       e0_.id AS id_8,
       COUNT(t1_.id) AS sclr_9,
       e0_.place_id AS place_id_10,
       e0_.organization_id AS organization_id_11,
       e0_.inner_image1_id AS inner_image1_id_12,
       e0_.inner_image2_id AS inner_image2_id_13,
       e0_.inner_image3_id AS inner_image3_id_14,
       e0_.image_id AS image_id_15
FROM event e0_
LEFT JOIN event_occurence e2_ ON e0_.id = e2_.event_id
LEFT JOIN ticket t1_ ON e2_.id = t1_.occurence_id
WHERE e0_.organization_id = '956744cb-6f76-4328-8ea5-c9715d762509'
GROUP BY e0_.id
LIMIT 100;

就發出的SQL請求而言,這正是我想要的。

問題是在ORM方面,結果是這樣組織的

[
   [ movie, nbrTickets],
   [ movie, nbrTickets],
   [ movie, nbrTickets],
]

我想知道如何給Doctrine提示,以便nbrTickets直接成為Movie的屬性,(目前我必須迭代自己),同時仍然只執行1個SQL查詢 (我非常強調,所以我不想做movie.tickets | length我的樹枝movie.tickets | length

答案應滿足以下要求:

  • 執行1個 SQL查詢(=>否則,因為我的頁面顯示100部電影,僅此會發出101條查詢)
  • 允許直接從實體內部訪問結果(=>否則如上所述,我已經有一個解決方案,可以檢索想要的數據,我有興趣讓代碼更加遵守ORM)
  • 不會檢索太多數據。

答案“目前尚無法用學說”也可以接受。

您需要適當的注釋才能在電影和票證實體中使用該關系。

電影實體:

 * One user has Many tickets.
 * @ORM\OneToMany(targetEntity="Ticket", mappedBy="user")
 */
private $tickets;

票證實體:

 * Many tickets have One movie.
 * @ORM\ManyToOne(targetEntity="movie", inversedBy="tickets")
 * @ORM\JoinColumn(name="movie_id", referencedColumnName="id")
 */
private $movie;

對於關系,您需要在構造函數中定義一個數組集合

public function __construct() {
    $this->tickets = new ArrayCollection();
}

您需要像這樣為Movie實體創建getTickets函數:

 * tickets
 *
 * @return arrayCollection
 */
public function getTickets()
{
    return $this->tickets;
}

然后,通過以下存儲庫調用檢索電影:

    $movies = $this->getDoctrine()
        ->getRepository('AppBundle:movies')
        ->findAll();

最后,您檢索票證:

    $tickets = $movies[0]->getTickets()

然后用以下方式計算它們:

    $tickets->count()

當前,似乎沒有簡單的方法可以直接將其映射到實體中。 您只能做一個近似的解決方案:(這可以完成工作,但不能那么優雅)

  • 使用$movie->tickets->count()這很優雅,但成本太高(每部電影您還要執行1個sql請求)
  • 使用addSelect (我當前的解決方案)執行一次請求以獲取所有數據,但需要其他代碼來映射您實體中的計數。

似乎在教義1中有一種解決方案,如此處所述因為您能夠從實體內部訪問包含非映射值的特殊屬性$this->_values ,情況似乎不再如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM