Tôi có mối quan hệ cha mẹ con giữa hai thực thể (Phụ huynh và Trẻ em).Xóa một mục khỏi bộ sưu tập (NHibernate)
lập bản đồ chuyên của tôi là như sau:
<class name="Parent" table="Parents">
...
<bag name="Children" cascade="all">
<key column="ParentID"></key>
<one-to-many class="Child"></one-to-many>
</bag>
</class>
Tôi muốn thực hiện như sau:
someParent.Children.Remove(someChild);
Lớp trẻ em có một tham chiếu đến một tầng lớp phụ huynh, Type. Mối quan hệ trông giống như
Lưu ý: Tôi xin lỗi vì sự url phi liên kết trên, tôi dường như không thể vượt qua các dấu hoa thị trong chuỗi url sử dụng Markup
Do này mối quan hệ, khi mã trên được gọi, thay vì một truy vấn DELETE, một truy vấn UPDATE được tạo ra để loại bỏ ParentID khỏi bảng con (đặt thành null).
Có thể buộc NHibernate xóa hoàn toàn bản ghi con, khi bị xóa khỏi bộ sưu tập Parent.Children không?
CẬP NHẬT
@ Giải pháp
giải pháp Rất hấp dẫn Spencer vì đây là một cái gì đó có thể được thực hiện trong các lớp học trong tương lai. Tuy nhiên, do các phiên làm việc được xử lý (trong trường hợp cụ thể của tôi) trong mẫu kho lưu trữ, điều này là gần như không thể vì chúng ta sẽ phải vượt qua các loại phiên (CallSessionContext/WebSessionContext) tùy thuộc vào ứng dụng.
@ Giải pháp của Jamie
Đơn giản và nhanh chóng thực hiện, tuy nhiên tôi đã nhấn một khối đường khác. Thực thể con tôi trông giống như sau:
Khi sử dụng phương pháp mới, NHibernate tạo tuyên bố cập nhật thiết lập TypeID và ParentID thành null, trái ngược với xóa hoàn toàn. Nếu tôi bỏ lỡ một cái gì đó trong quá trình thực hiện, hãy cho tôi biết vì phương pháp này sẽ không đau để tiến lên phía trước.
@The One-Shot-Delete solution described here, phác thảo một ý tưởng hủy kết hợp bộ sưu tập để buộc xóa một lần. Kết quả tương tự như trên tuy nhiên, một tuyên bố cập nhật được ban hành.
//Instantiate new collection and add persisted items
List<Child> children = new List<Child>();
children.AddRange(parent.Children);
//Find and remove requested items from new collection
var childrenToRemove = children
.Where(c => c.Type.TypeID == 1)
.ToList();
foreach (var c in childrenToRemove) { children.Remove(m); }
parent.Children = null;
//Set persisted collection to new list
parent.Children = Children;
Giải pháp
Took một chút đào, nhưng giải pháp của Jamie đã qua với một số sửa đổi bổ sung. Đối với độc giả trong tương lai, dựa trên mô hình của tôi lớp trên:
Loại bản đồ - Inverse = true, Cascade = tất cả các bản đồ chuyên
- Inverse = true, Cascade = all-xóa-mồ côi
Hủy bỏ các phương pháp như được mô tả trong các giải pháp của Jamie.Điều này tạo ra một tuyên bố xóa duy nhất cho mỗi mục mồ côi, vì vậy có khả năng điều chỉnh trong tương lai, tuy nhiên kết quả cuối cùng là thành công.
Tôi tin rằng điều này có thể đã làm tôi ngạc nhiên trên con đường bên phải, khối đường đang được: thiết lập trong mô hình kho lưu trữ (ví dụ, trong trường hợp này phương thức Delete sẽ gọi phương thức lưu trữ của chính nó) và cũng có thể sử dụng điều này với ngữ cảnh phiên khác nhau (ví dụ: CallSessionContext vs WebSessionContext) –