Bạn có thể ánh xạ kết quả một cột cho một trường thực thể - xem truy vấn gốc và ResultSetMapping để đạt được điều này. Ví dụ đơn giản:
use Doctrine\ORM\Query\ResultSetMapping;
$sql = '
SELECT p.*, COUNT(r.id)
FROM products p
LEFT JOIN reviews r ON p.id = r.product_id
';
$rsm = new ResultSetMapping;
$rsm->addEntityResult('AppBundle\Entity\Product', 'p');
$rsm->addFieldResult('p', 'COUNT(id)', 'reviewsCount');
$query = $this->getEntityManager()->createNativeQuery($sql, $rsm);
$results = $query->getResult();
Sau đó, trong thực thể Sản phẩm của bạn, bạn sẽ có $reviewsCount
trường và số lượng sẽ được ánh xạ tới trường đó. Lưu ý rằng điều này sẽ chỉ hoạt động nếu bạn có một cột được xác định trong siêu dữ liệu Doctrine, như sau:
/**
* @ORM\Column(type="integer")
*/
private $reviewsCount;
public function getReviewsCount()
{
return $this->reviewsCount;
}
Đây là những gì được gợi ý bởi Trường tổng hợp
Tài liệu giáo lý. Vấn đề ở đây là về cơ bản, bạn đang làm cho Doctrine nghĩ rằng bạn có một cột khác trong cơ sở dữ liệu của mình có tên là reviews_count
, đó là điều bạn không muốn. Vì vậy, điều này sẽ vẫn hoạt động mà không cần thêm cột đó về mặt vật lý, nhưng nếu bạn đã từng chạy doctrine:schema:update
nó sẽ thêm cột đó cho bạn. Rất tiếc, Doctrine không thực sự cho phép các thuộc tính ảo, vì vậy, một giải pháp khác sẽ là viết trình điều chỉnh độ ẩm tùy chỉnh của riêng bạn hoặc có thể đăng ký loadClassMetadata
sự kiện và tự thêm ánh xạ theo cách thủ công sau khi thực thể (hoặc các thực thể) cụ thể của bạn tải.
Lưu ý rằng nếu bạn làm điều gì đó như COUNT(r.id) AS reviewsCount
thì bạn không thể sử dụng COUNT(id)
được nữa trong addFieldResult()
của bạn và thay vào đó phải sử dụng bí danh reviewsCount
cho tham số thứ hai đó.
Bạn cũng có thể sử dụng ResultSetMappingBuilder
khi bắt đầu sử dụng ánh xạ tập kết quả.
Đề xuất thực tế của tôi là làm điều này theo cách thủ công thay vì thực hiện tất cả những thứ bổ sung đó. Về cơ bản, hãy tạo một truy vấn bình thường trả về cả thực thể và kết quả vô hướng của bạn vào một mảng, sau đó đặt kết quả vô hướng thành một trường tương ứng, chưa được ánh xạ trên thực thể của bạn và trả về thực thể.