Tôi có hai thực thể trong một mối quan hệ hai chiều one-to-many:Làm cách nào để thay đổi cha mẹ của trẻ trong NHibernate khi thác là xóa toàn bộ trẻ mồ côi?
public class Storage
{
public IList<Box> Boxes { get; set; }
}
public class Box
{
public Storage CurrentStorage { get; set; }
}
Và ánh xạ:
<class name="Storage">
<bag name="Boxes" cascade="all-delete-orphan" inverse="true">
<key column="Storage_Id" />
<one-to-many class="Box" />
</bag>
</class>
<class name="Box">
<many-to-one name="CurrentStorage" column="Storage_Id" />
</class>
Một Storage
có thể có nhiều Boxes
, nhưng một Box
chỉ có thể thuộc về một Storage
. Tôi đã ánh xạ chúng sao cho một người có nhiều tầng là all-delete-orphan
.
Sự cố của tôi nảy sinh khi tôi cố gắng thay đổi Hộp Storage
. Giả sử tôi đã chạy mã này:
var storage1 = new Storage();
var storage2 = new Storage();
storage1.Boxes.Add(new Box());
Session.Create(storage1);
Session.Create(storage2);
Đoạn mã dưới đây sẽ cung cấp cho tôi một ngoại lệ:
// get the first and only box in the DB
var existingBox = Database.GetBox().First();
// remove the box from storage1
existingBox.CurrentStorage.Boxes.Remove(existingBox);
// add the box to storage2 after it's been removed from storage1
var storage2 = Database.GetStorage().Second();
storage2.Boxes.Add(existingBox);
Session.Flush(); // commit changes to DB
tôi nhận được ngoại lệ sau đây:
NHibernate.ObjectDeletedException: đối tượng bị xóa sẽ được lưu lại bằng cách xếp chồng (xóa đối tượng đã xóa khỏi các liên kết)
Trường hợp ngoại lệ này xảy ra vì tôi đã đặt tầng thác là all-delete-orphan
. Đầu tiên Storage
phát hiện rằng tôi đã xóa Box
khỏi bộ sưu tập của nó và đánh dấu nó để xóa. Tuy nhiên, khi tôi thêm nó vào thứ hai Storage
(trong cùng một phiên), nó cố gắng để lưu hộp một lần nữa và ObjectDeletedException
được ném.
Câu hỏi của tôi là, làm cách nào để nhận được số Box
để thay đổi phụ huynh Storage
mà không gặp phải ngoại lệ này? Tôi biết một giải pháp có thể là để thay đổi các thác chỉ all
, nhưng sau đó tôi mất khả năng có NHibernate tự động xóa một Box
bằng cách loại bỏ nó từ một Storage
và không tái kết hợp nó với một số khác. Hay đây là cách duy nhất để làm điều đó và tôi phải tự gọi Session.Delete
trên hộp để xóa nó?
Điều gì sẽ xảy ra nếu bạn không bao giờ xóa hộp khỏi bộ nhớ 1? Nếu bạn chỉ di chuyển nó vào bộ nhớ 2, liệu CurrentStorage có bị ghi đè không? Tôi không chắc chắn nếu điều đó hoạt động nếu storage1 đã được nạp trong phiên. – dotjoe
Nó hoạt động, nhưng cho đến khi tôi làm mới các thực thể của tôi, tôi sẽ có một bản sao của hộp trong cả hai kho. Tôi muốn có mô hình dữ liệu của tôi được chính xác hơn là dựa vào NHib để làm điều đúng khi tôi lấy thực thể. –
À vâng, đứa trẻ mồ côi sẽ luôn bị xóa nếu bạn xóa khỏi bộ sưu tập. Tôi nghĩ trong trường hợp này bạn muốn làm như bạn đã nói ở phần cuối, bạn muốn 'cascade =" all "' và xóa một hộp bằng cách xóa khỏi bộ sưu tập và gọi 'session.Delete (box)'. Tôi không nghĩ rằng bạn có thể có tốt nhất của cả hai thế giới: ( – dotjoe