2017-03-12 129 views
0

我試圖在查詢與另一個實體有關係的實體時做出一些有效的改進。學說連接實體

實體答:

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

/** 
* @var string 
* @ORM\Column(name="name", type="string", length=225) 
* @Assert\NotBlank(message="Please enter a name for your profile.") 
*/ 
protected $display_name; 

/** 
* @ORM\OneToOne(targetEntity="Posts", mappedBy="profile", cascade={"all"}, fetch="LAZY") 
*/ 
protected $posts; 

實體B:

/** 
* @var integer 
* @ORM\Column(name="profile_id", type="integer") 
* @ORM\Id 
*/ 
protected $profile_id; 

/** 
* @ORM\OneToOne(targetEntity="Profile", inversedBy="posts") 
* @ORM\JoinColumn(name="profile_id", referencedColumnName="id") 
*/ 
protected $profile; 

/** 
* @var string 
* @ORM\Column(name="content", type="string") 
*/ 
protected $content; 

當我數正在執行的查詢號碼,我得到兩個,我想是的學說運行爲每個實體甚至通過兩個單獨的查詢他們有關係。

我目前獲取實體A像這樣:

public function fetchById($id) 
{ 
    return $this->createQueryBuilder('p') 
     ->where('p.id = :id') 
     ->setParameter('id', $id) 
     ->getQuery() 
     ->getOneOrNullResult(); 
} 

,然後調用實體B像這樣:

$profile = $profileRepository->fetchById($user->getUserId()); 
$lastpost = $profile->getPosts()[0]; 

但我希望能夠參加第二實體在此查詢,以便我可以只調用一個查詢而不是兩個。我希望能做這樣的事情:

public function fetchById($id) 
{ 
    return $this->createQueryBuilder('p') 
     ->select('p','pp') 
     ->leftJoin(Posts::class, 'pp', \Doctrine\ORM\Query\Expr\Join::WITH, 'p.id = pp.profile_id') 
     ->where('p.id = :id') 
     ->setParameter('id', $id) 
     ->getQuery() 
     ->getResults(); 
} 

然而,左連接返回兩個實體的數組。這不是我想要的,因爲我想仍然可以調用實體A中的getPosts()方法。

我基本上想要填充實體A,包括所有相關實體。但是通過只執行一個查詢而不是兩個,這在教義中是可行的嗎?

回答

1

前一段時間我也有類似的情況(不與1-1,但1-N雖然),這是我解決這樣的:

// ...Repository 
public function findAllForUserWithAll(\AppBundle\Entity\User $u) 
{ 
    $query = $this->getEntityManager()->createQueryBuilder('ca1') 
     ->add('select', 'c, s, i, m') 
     ->add('from', 'AppBundle:Contact c') 
     ->leftJoin('c.skills', 's') 
     ->leftJoin('c.interests', 'i') 
     ->leftJoin('c.metAt', 'm') 
     ->where('c.user = :user') 
     ->orderBy('c.lastname', 'ASC') 
     ->setParameters([ 
      'user' => $u, 
     ]) 
     ->getQuery(); 

    return $query->getResult(); 
} 

這是Symfony的2.8 * ^學說2.4。 8 - 結果是一個帶有3個連接的查詢(而不是4個查詢)。可能不是最好的代碼,老實說,所有的魔法都發生在引擎蓋下。你的代碼看起來也很相似。但也許這是由於fetch="LAZY"(在實體A上) - 我的實體沒有?

+0

使3個連接效率低下f *** –

+0

@mike在我的情況下,它可能比運行100個查詢更有效率,1+(n * 3)精確 – kero

+1

在你的情況下,你應該有一個視圖模型它彙總了一個表格中的所有內容,並針對應用程序的視圖部分進行了優化。 –