cascade = {“remove”} VS orphanRemoval = true VS ondelete = "CASCADE


93

Tôi đã cố gắng thu thập một số thông tin về những cách sau để xóa thực thể con tự động khi thực thể mẹ bị xóa. Có vẻ như cách phổ biến nhất là sử dụng một trong ba chú thích đó: cascade = {"remove"} OR orphanRemoval = true OR ondelete = "CASCADE" .

Tôi hơi nhầm lẫn về cái thứ ba: ondelete = "CASCADE" , vì lời giải thích trong tài liệu chính thức về học thuyết về cái này rất hiếm) và tôi rất muốn ai đó có thể xác nhận cho tôi những thông tin sau mà tôi thu thập và hiểu được từ nghiên cứu của mình về net và kinh nghiệm ...

NHỮNG GÌ NÓ LÀM

cascade = {"remove"}
==> thực thể ở phía nghịch đảo bị xóa khi thực thể phía sở hữu được. Ngay cả khi bạn đang ở trong nhiều tổ chức với thực thể bên sở hữu khác.
- nên được sử dụng trên bộ sưu tập (vì vậy trong mối quan hệ OneToMany hoặc ManyToMany)
- triển khai trong ORM

orphanRemoval = true
==> thực thể ở phía nghịch đảo bị xóa khi thực thể bên sở hữu VÀ nó không được kết nối với bất kỳ thực thể bên sở hữu nào khác nữa. (tham chiếu học thuyết official_doc - triển khai trong ORM
- có thể được sử dụng với OneToOne, OnetoMany hoặc ManyToMany

onDelete = "CASCADE"
==> điều này sẽ thêm On Delete Cascade vào cột khóa ngoại trong cơ sở dữ liệu
- Chiến lược này hơi khó để làm đúng nhưng có thể rất mạnh và nhanh. (tham khảo học thuyết chính thức_doc ... nhưng chưa đọc thêm giải thích)
- ORM phải làm ít công việc hơn (so với hai cách làm trước đây) và do đó sẽ có hiệu suất tốt hơn.

thông tin khác
- tất cả 3 cách làm đó đều được triển khai trên các thực thể quan hệ nhà thầu ( phải không ??? )
- sử dụng cascade = {"remove"} hoàn toàn bỏ qua bất kỳ khóa ngoại nào onDelete = CASCADE. (tham khảo học thuyết_official_doc )

VÍ DỤ VỀ CÁCH SỬ DỤNG NÓ TRONG MÃ

  • orphanRemoval và cascade = {"remove"} được xác định trong lớp thực thể đảo ngược.
  • ondelete = "CASCADE" được xác định trong thực thể chủ sở hữu
  • bạn cũng có thể chỉ cần viết @ORM \ JoinColumn (onDelete = "CASCADE") và để học thuyết xử lý tên cột

cascade = {"remove"}

/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", cascade={"remove"})
*/
protected $Phonenumbers

orphanRemoval = true

/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", orphanRemoval=true)
*/
protected $Phonenumbers

onDelete = "CASCADE"

/** 
* @ManyToOne(targetEntity="Contact", inversedBy="phonenumbers")
* @JoinColumn(name="contact_id", referencedColumnName="contact_id", onDelete="CASCADE")
*/ 
protected $contact; 

1
nó có một lời giải thích tốt stackoverflow.com/questions/25515007/…
Gregsparrow

Câu trả lời:


61

onDelete="CASCADE"được quản lý bởi chính cơ sở dữ liệu. cascade={"remove"}được quản lý bằng học thuyết.

onDelete="CASCADE"nhanh hơn vì các hoạt động được thực hiện ở cấp độ cơ sở dữ liệu thay vì theo học thuyết. Việc loại bỏ được thực hiện bởi máy chủ cơ sở dữ liệu chứ không phải Doctrine. Với cascade={"remove"}học thuyết phải quản lý chính thực thể đó và sẽ thực hiện kiểm tra thêm để xem liệu nó không có bất kỳ thực thể sở hữu nào khác hay không. Khi không có cái nào khác tồn tại, nó sẽ xóa thực thể. Nhưng điều này tạo ra chi phí cao.


cascade = {"remove"}

  • thực thể bên nghịch đảo bị xóa khi thực thể bên sở hữu. Ngay cả khi bạn đang ở trong nhiều tổ chức với thực thể bên sở hữu khác. Không, nếu thực thể thuộc sở hữu của thứ khác. Nó sẽ không bị xóa.
  • nên được sử dụng trên bộ sưu tập (vì vậy trong mối quan hệ OneToMany hoặc ManyToMany)
  • triển khai trong ORM

orphanRemoval = "true"

  • thực thể ở phía nghịch đảo bị xóa khi thực thể bên sở hữu VÀ nó không được kết nối với bất kỳ thực thể bên sở hữu nào khác nữa. Không chính xác, điều này làm cho học thuyết hoạt động như thể nó không thuộc sở hữu của một thực thể khác, và do đó loại bỏ nó.
  • triển khai trong ORM
  • có thể được sử dụng với OneToOne, OnetoMany hoặc ManyToMany

onDelete = "CASCADE"

  • điều này sẽ thêm On Delete Cascade vào cột khóa ngoại TRONG CƠ SỞ DỮ LIỆU
  • Chiến lược này hơi khó để đi đúng nhưng có thể rất hiệu quả và nhanh chóng. (đây là một trích dẫn từ hướng dẫn chính thức của giáo lý ... nhưng chưa thấy giải thích nhiều hơn)
  • ORM phải làm ít công việc hơn (so với hai cách làm trước đây) và do đó sẽ có hiệu suất tốt hơn.

3
@ waaghals. Về nhận xét của bạn trên cascade = {"remove"} ==> Tôi có mối quan hệ ManyToMany giữa thực thể Article và Category. Khi tôi xóa một Bài báo ($ em-> remove ($ article);), nó sẽ xóa tất cả các danh mục được liên kết với bài viết này NGAY CẢ nếu các danh mục đó cũng được liên kết với các bài viết khác. vì vậy tôi sẽ nói rằng nó không hoạt động như bạn viết.
Alexis_D

2
@ waaghals. Về nhận xét của bạn trên orphanRemoval = "true" Câu tôi đã viết "thực thể ở phía nghịch đảo bị xóa khi thực thể bên sở hữu và nó không thuộc sở hữu của bất kỳ thực thể nào khác" được trích dẫn từ các trang chính thức của học thuyết. học thuyết = orphanremoval .
Alexis_D

1
@Alexis_D, hoàn toàn đồng ý với ý kiến của bạn Câu trả lời là không chính xác và có thể được thực sự khó hiểu cho người mới
Stepan Yudin

3
Một trong những ví dụ rõ ràng hơn mà tôi đã đọc: gist.github.com/pylebecq/f844d1f6860241d8b025
Victor S

Liên kết @VictorS 'rất rõ ràng. Tôi không còn làm việc với Doctrine nữa nên cảm thấy rằng tôi không thể cập nhật câu trả lời của mình nếu không biết cách hoạt động của nó. Nếu ai đó có thể cập nhật câu trả lời của tôi thì điều đó thật tuyệt.
Waaghals
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.