2010-11-05 31 views
30

Tôi có 2 thực thể: Quốc gia (id, tên) và Ánh xạ (id, đối tượng, internalId, externalId). Quốc gia và Ánh xạ không được kết nối với các liên kết (vì Ánh xạ có các hàng không chỉ cho quốc gia). Tôi cần phải nhận được id bên ngoài cho các nước sử dụng điều kiện sau đây:Sử dụng EntityManager bên trong các thực thể Doctrine 2.0

  • country.id = mapping.internalId
  • mapping.object = 'country'

Vì vậy, tôi có kế hoạch để thêm chức năng getExternalId() trong Nước

function getExternalId() { 
    $em = Registry::getEntityManager(); 

    $mapping = $em->getRepository('Mapping')->findOneBy(array(
     'object'  => 'country', 
     'internalId' => $this->getId() 
    )); 

    return !empty($mapping) ? $mapping->getExternalId() : false; 
} 

Câu hỏi:

  1. Có thực hành tốt để sử dụng EntityManager bên trong thực thể? Nếu không, vui lòng giải thích cách nhận id bên ngoài trong trường hợp của tôi?
  2. Có thể liên kết Quốc gia và Ánh xạ bằng tệp yaml?

Cảm ơn bạn trước!

Trả lời

51

Không nên cho phép đối tượng thực thể dựa vào trình quản lý đối tượng. Nó liên kết thực thể với lớp persistence, đó là một vấn đề mà Doctrine 2 đã cố gắng giải quyết. Những rắc rối lớn nhất trong việc dựa vào người quản lý thực thể là nó làm cho mô hình của bạn khó kiểm tra trong sự cô lập, cách xa cơ sở dữ liệu.

Bạn có lẽ nên dựa vào các đối tượng dịch vụ để xử lý các hoạt động dựa trên trình quản lý thực thể.

// CountryService 
public function getExternalId($country) {} 

Ngoài ra, bạn có thể tạo phương thức proxy trên mô hình của mình để gọi ra đối tượng dịch vụ được đặt bên ngoài. Một đối tượng dịch vụ sẽ dễ dàng hơn nhiều khi thử nghiệm trong khi thử nghiệm hơn trình quản lý thực thể.

$country->setService($countryService); 
$country->getExternalId(); 

// Country 
public function getExternalId() 
{ 
    $this->_service->getExternalId($this); 
} 
+6

Tôi đang tìm kiếm các hướng dẫn tốt về triển khai dịch vụ cho học thuyết. Có ai biết hướng dẫn tốt. – user257980

+0

Đối tượng dịch vụ trong trường hợp này có cần phải là nội bộ của thực thể hoặc bạn có thể sử dụng nó với pháp nhân không? ví dụ. $ service = new Quốc gia \ ServiceObject; $ ExtId = $ service-> getExternalId ($ country); – calumbrodie

+0

triển khai dịch vụ cho học thuyết: http://symfony.com/doc/current/book/service_container.html – bleuscyther

8

Tôi nghĩ những gì bạn cần sử dụng là các kho lưu trữ thực thể. Đây là những chi tiết trong tài liệu, mặc dù một chút khó khăn để tìm thông tin trên. Đây là một liên kết đến bài viết Getting Started có tài liệu về cách người ta sẽ tạo một "kho lưu trữ" các chức năng 'truy cập' cho các thực thể của bạn.

Ngoài ra đây là một số mã giả để giúp bạn bắt đầu:

<?php 
// repositories/CountryRepository.php 

use Doctrine\ORM\EntityRepository; 

class CountryRepository extends EntityRepository 
{ 
    public function getExternalId() 
    { 
+0

có vẻ như liên kết đã chết – Gigala

+1

Tại thời điểm này, liên kết đang hoạt động. Tôi nghĩ rằng đây là một giải pháp rất tốt cho câu hỏi của OP. –

1

Một chút cắt cạnh phụ lục này (PHP 5.4 là ở alpha 2 tại thời điểm bài viết này) có thể được sử dụng trong việc trong tương lai:

Here là một số ví dụ về việc sử dụng các đặc điểm php 5.4 trong Doctrine2; một trong số đó được gọi là thực thể hoạt động và cung cấp chức năng kiểu bản ghi đang hoạt động trong Doctrine 2 bao gồm quyền truy cập vào trình quản lý thực thể từ bên trong thực thể.

9

Đây có thể không phải là ý tưởng hay nhất, nhưng có một cách đơn giản để thực hiện việc này.

Lớp học UnitOfWork trong học thuyết sẽ hydrat bất kỳ thực thể nào triển khai ObjectManagerAware với trình quản lý thực thể và siêu dữ liệu lớp cho thực thể đó.

Tất cả bạn phải làm để có được máng cỏ đơn vị trong tổ chức của bạn là thực hiện giao diện như trong ví dụ dưới đây:

use Doctrine\Common\Persistence\Mapping\ClassMetadata; 
use Doctrine\Common\Persistence\ObjectManager; 
use Doctrine\Common\Persistence\ObjectManagerAware; 

/** 
* @ORM\Entity 
*/ 
class MyEntity implements ObjectManagerAware 
{ 
    public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata) 
    { 
     $this->em = $objectManager; 
    } 
} 

Nếu bạn tạo một thực thể mới hơn là truy vấn nó từ cơ sở dữ liệu, bạn sẽ cần phải thiết lập trình quản lý thực thể theo cách thủ công, ví dụ như với một phương thức setter.

+0

Công việc tuyệt vời @peterjwest :) – juanmf

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