2012-11-28 25 views
5

Đầu tiên tôi sẽ đưa ra một ví dụ với một số mã giả và sau đó tôi sẽ giải thích vấn đề là gì. Hãy để tôi nói rằng tôi có hai thực thể Người dùng và Phonenumber. Mối quan hệ của họ là một-nhiều. Trong UserRepository của tôi, tôi có thể có một cái gì đó như thế:Doctrine fetch join

class UserRepository 
{ 
    public function getUser($id, $type) 
    { 
     $users = $this->createQuery("SELECT u, p FROM User u JOIN u.phonenumbers p 
      WHERE u.id = :id AND p.type = :type") 
      ->setParameters(array(
       'id' => $id, 
       'type' => $type, 
      )) 
      ->getResult(); 
     return $users[0]; 
    } 
} 

trong ứng dụng của tôi nếu tôi có cái gì đó như:

$user = $userRepo->getUser(1, 'home'); 
var_dump($user->getPhonenumbers()); // here phonenumbers collection is ok 

$user = $userRepo->getUser(1, 'work'); 
var_dump($user->getPhonenumbers()); // Here phonenumbers collection is wrong. 
           // It's exactly the same as the previous one. 

Vì vậy, câu hỏi của tôi là: Có thể sử dụng lấy tham gia (với các tiêu chí khác nhau) và để có được bộ sưu tập phù hợp mỗi lần?

Trả lời

3

Tìm nạp và lọc bộ sưu tập không phải là những thứ hoạt động tốt. Đây là cách bạn nên làm điều đó:

SELECT 
    u, p 
FROM 
    User u 
JOIN 
    u.phonenumbers p 
JOIN 
    u.phonenumbers p2 
WHERE 
    u.id = :id 
    AND 
    p2.type = :type 

này áp dụng lọc ngày thứ hai tham gia (và không ngậm nước) p2, mà kết quả trong đúng hydrat hóa và lọc.

+0

Hiện tại tôi đã sử dụng Truy vấn :: HINT_REFRESH, điều tôi tin rằng sẽ có một số tác động về hiệu suất, nhưng chắc chắn tôi sẽ kiểm tra giải pháp của bạn. Cảm ơn vì đã dành thời gian cho tôi. – ventsislaf

-2

Sử dụng trình tạo truy vấn, nó đơn giản hơn rất nhiều.

public function getUser($id, $type) 
{ 
    return $this->createQueryBuilder("u") 
     ->leftJoin("u.Phonenumbers", "p", "WITH", "p.type=:type") 
     ->where("u.id=:id") 
     ->setParameters(.....) 
     ->getQuery() 
     ->getOneOrNullResult() ; 
} 
+0

Ví dụ này chỉ là một mã giả. Vấn đề là trong hành vi của giáo lý, không phải trong mã được cung cấp. – ventsislaf

+0

Vẫn như cũ, sử dụng câu lệnh leftJoin và WITH cho dù bạn xây dựng các truy vấn như thế nào. – Zeljko

+0

Ví dụ không chính xác. – Ocramius