2012-11-18 19 views
13

Câu hỏi đặt ra là về Doctirne nhưng tôi nghĩ rằng có thể được mở rộng cho nhiều ORM.Tại sao có nhu cầu tách và hợp nhất các thực thể trong ORM?

Detach:

Một thực thể được tách ra từ một EntityManager và do đó không còn được quản lý bằng cách gọi phương pháp EntityManager#detach($entity) vào nó hoặc bằng tầng hoạt động Mở cửa sổ mới với nó. Các thay đổi được thực hiện cho thực thể tách rời , nếu có (bao gồm xóa đối tượng), sẽ không được đồng bộ hóa với cơ sở dữ liệu sau khi thực thể được tách ra.

Merge:

đơn vị sáp nhập liên quan đến việc sáp nhập các đơn vị (thường tách ra) vào bối cảnh của một EntityManager để họ trở thành quản lý một lần nữa. Để hợp nhất trạng thái của một thực thể thành một EntityManager, hãy sử dụng phương thức EntityManager#merge($entity). Trạng thái của thực thể đã qua sẽ được hợp nhất thành bản sao được quản lý của đối tượng này và bản sao này sẽ sau đó sẽ được trả lại.

Tôi hiểu (gần như) cách thức này hoạt động, nhưng câu hỏi đặt ra là: tại sao người ta cần tách ra/sáp nhập entitiies? Bạn có thể cho tôi một ví dụ/kịch bản khi hai hoạt động này có thể được sử dụng/cần thiết không?

Trả lời

14

Khi nào tôi nên tách một thực thể?
Tách một thực thể từ một EM (EntityManager) được sử dụng rộng rãi khi bạn đối phó với nhiều hơn một EM và tránh những xung đột đồng thời, ví dụ:

$user= $em->find('models\User', 1); 
$user->setName('Foo'); 

// You can not remove this user, 
// because it still attached to the first Entity Manager 
$em2->remove($user); 
$em2->flush(); 

Bạn không thể kiểm soát $user đối tượng bằng cách $em2 vì phiên của nó thuộc về $em mà ban đầu tải $user từ cơ sở dữ liệu. Họ làm thế nào để giải quyết vấn đề trên? Bạn cần phải tách đối tượng:

$user= $em->find('models\User', 1); 
$user->setName('Foo'); 

$em2->detach($user); 
$em2->remove($user); 
$em2->flush(); 

Khi nào tôi nên sử dụng chức năng hợp nhất?
Về cơ bản khi bạn muốn cập nhật một thực thể:

$user= $em->find('models\User', 1); 
$user->setName('Foo'); 

$em->merge($user); 
$em->flush(); 

Các EM sẽ làm một so sánh giữa người sử dụng $ trong cơ sở dữ liệu vs người dùng $ trong bộ nhớ. Khi EM nhận ra các trường đã thay đổi, nó chỉ cập nhật chúng và giữ các trường cũ.

Phương pháp flush gây ra một cam kết và tên người dùng sẽ được cập nhật trong cơ sở dữ liệu

+0

Tôi đồng ý với tất cả nói ngoại trừ những gì được nói về tuôn ra. Phương thức tuôn ra đồng bộ hóa các thực thể với cơ sở dữ liệu nhưng bên trong các ranh giới giao dịch. Điều này xuất phát khi gọi một truy vấn trong cùng một giao dịch. Vì vậy, bạn kiểm dịch rằng việc xử lý truy vấn sẽ tính đến các cập nhật giao dịch rất này. – Sam

+0

Bạn là đúng @Sam, tôi đã sai với phương pháp tuôn ra. – manix

+1

Đây là một lời giải thích tốt (+1), nhưng tại sao một người nên sử dụng nhiều hơn một người quản lý thực thể ngay từ đầu? Không thể lấy nó, xin lỗi, sử dụng Doctrine luôn với một trình quản lý thực thể ... – gremo

1

Bạn sẽ cần phải tách một thực thể khi đối phó với vấn đề đồng thời.

Giả sử bạn đang sử dụng API không đồng bộ làm cho cuộc gọi lại đến dự án của bạn. Khi bạn phát hành lệnh gọi API cùng với lệnh gọi lại, bạn có thể vẫn đang quản lý thực thể bị ảnh hưởng bởi cuộc gọi lại và do đó ghi đè các thay đổi được thực hiện bởi cuộc gọi lại.

-1

Bạn cũng có thể tách thực thể khi bạn có dữ liệu trong cơ sở dữ liệu, nhưng trong mã của bạn, bạn sửa đổi các thực thể này tùy thuộc vào tài khoản người dùng.

Ví dụ trò chơi trình duyệt có một số ký tự và một số cuộc tấn công để chiến đấu. AttackOne sử dụng bởi "UserFoo" (lvl 90) sẽ được sửa đổi bởi tiền thưởng tốt hơn so với sử dụng bởi "UserBarr" (lvl 20), nhưng trong cơ sở dữ liệu của chúng tôi AttackOne tất cả các thời gian là như nhau tấn công

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