2011-11-21 32 views
16

Tôi đang làm việc trên một trang web sự kiện và có một đến nhiều mối quan hệ giữa sản xuất và biểu diễn của mình, khi tôi có một đối tượng thực hiện nếu tôi cần id sản xuất của nó vào lúc này tôi phải làmBạn có thể lấy khóa ngoại từ một đối tượng trong Doctine2 mà không tải đối tượng đó không?

$productionId = $performance->getProduction()->getId(); 

Trong trường hợp khi tôi thực sự chỉ cần id sản xuất, nó có vẻ như một sự lãng phí để gửi ra một truy vấn cơ sở dữ liệu khác để có được một giá trị đã có trong đối tượng ở đâu đó. Có đường vòng này không?

+3

Câu hỏi hay - Tôi thường xuyên tham gia và muốn tìm cách truy cập trực tiếp giá trị khóa ngoại mà không phải tham gia liên kết mỗi lần. – cantera

Trả lời

27

Chỉnh sửa 2013.02.17:
Điều tôi viết dưới đây không còn đúng nữa. Bạn không phải làm bất cứ điều gì trong kịch bản được nêu trong câu hỏi, vì Doctrine đủ thông minh để tải các trường id vào các thực thể liên quan, vì vậy các đối tượng proxy sẽ chứa id và nó sẽ không đưa ra một cuộc gọi nào khác kho dữ liệu.

Câu trả lời lỗi thời bên dưới:

Có thể, nhưng không được khuyến khích. Lý do đằng sau đó là Doctrine cố thực sự tuân thủ nguyên tắc rằng các thực thể của bạn nên tạo thành một đồ thị đối tượng, nơi các khóa ngoại không có chỗ, bởi vì chúng chỉ là "hiện vật", đến từ cơ sở dữ liệu quan hệ công việc.

Bạn nên viết lại các hiệp hội để được

  • háo hức được nạp, nếu bạn luôn cần các tổ chức có liên quan
  • viết một truy vấn DQL (tốt nhất là trên một Repository) để lấy-tham gia tổ chức có liên quan
  • để cho nó lười biếng tải các thực thể liên quan bằng cách gọi một getter trên nó

Nếu bạn không tin, và thực sự muốn tránh tất cả những điều trên, có hai cách (mà tôi biết), để có được t id của một đối tượng liên quan, không kích hoạt tải và không sử dụng các thủ thuật như phản chiếu và tuần tự hóa:

Nếu bạn đã có đối tượng trong tay, bạn có thể truy xuất đối tượng bên trong mà Doctrine sử dụng trong nội bộ và sử dụng Phương pháp getEntityIdentifier(), chuyển cho đối tượng không tải (đối tượng proxy). Nó sẽ trả về cho bạn id, mà không kích hoạt tải lười.

Giả sử bạn có nhiều-một mối quan hệ, với nhiều bài viết thuộc về một thể loại:

$articleId = 1; 
$article = $em->find('Article', $articleId); 
$categoryId = $em->getUnitOfWork()->getEntityIdentifier($article->getCategory()); 

Coming 2.2, bạn sẽ có thể sử dụng chức năng DQL SẮC, để chọn chỉ là một chính nước ngoài, như thế này:

SELECT IDENTITY(u.Group) AS group_id FROM User u WHERE u.id = ?0 

Đây là already committed cho các phiên bản phát triển.

Tuy nhiên, bạn thực sự nên cố gắng gắn bó với một trong các phương pháp "chính xác".

+0

Cảm ơn câu trả lời của bạn, chỉ cần cho nó một đi và nó đã làm việc hoàn hảo!Loại tình huống mà tôi muốn làm là tạo ra các khuyến nghị, tôi có một số buổi biểu diễn và cần các id sản xuất để tôi có thể chuyển chúng đến một đối tượng sẽ tạo ra các khuyến nghị dựa trên các id sản xuất. Vì vậy, có vẻ như một chút không cần thiết để tải các sản phẩm khi tôi không cần chúng và tôi không thực sự muốn có hai phiên bản của hệ thống đề xuất của tôi. Tôi lấy ý kiến ​​của bạn về việc sử dụng hệ thống chính xác nhưng trong trường hợp này, lấy các id chỉ có vẻ là cách đơn giản nhất. – pogo

+3

Có nhiều trường hợp sử dụng, nơi bạn chỉ cần ID của một đối tượng liên quan. Tôi nghĩ vì lợi ích của việc điều chỉnh hiệu suất, nó được khuyến khích để phá vỡ với khái niệm OOP. Đó là vào cuối chỉ một sự hỗ trợ mà không nên làm chậm ứng dụng của bạn. Tôi rất biết ơn các giải pháp Noberts nhưng không phải với anh ấy về lập trường khái niệm của anh ấy. – bekay

Các vấn đề liên quan