Tôi có một thực thể được gọi là Sách có thể có danh sách nhiều sách hơn được gọi là RelatedBooks.Thành thạo NHibernate Tự Tham khảo Nhiều người Nhiều người
Các thực thể Sách viết tắt trông giống thích này:
public class Book
{
public virtual long Id { get; private set; }
public virtual IList<Book> RelatedBooks { get; set; }
}
Đây là những gì các bản đồ trông giống như đối với mối quan hệ này
HasManyToMany(x => x.RelatedBooks)
.ParentKeyColumn("BookId")
.ChildKeyColumn("RelatedBookId")
.Table("RelatedBooks")
.Cascade.SaveUpdate();
Dưới đây là một ví dụ về các dữ liệu mà sau đó được tạo ra trong Bảng RelatedBooks:
BookId RelatedBookId
1 2
1 3
Sự cố xảy ra khi tôi thử để xóa một cuốn sách. Nếu tôi xóa sách có ID là 1, mọi thứ đều hoạt động tốt và bảng RelatedBooks có hai bản ghi tương ứng bị xóa. Tuy nhiên nếu tôi cố gắng xóa các cuốn sách với một ID của 3, tôi nhận được lỗi "Tuyên bố DELETE xung đột với các hạn chế REFERENCE" FK5B54405174BAB605 ". Xung đột xảy ra trong cơ sở dữ liệu" Test ", bảng" dbo.RelatedBooks ", cột 'RelatedBookId ''.
Về cơ bản những gì đang xảy ra là không thể xóa sách vì bản ghi trong bảng RelatedBooks có phần tử liên quan đến 3 không bao giờ bị xóa.
Làm cách nào để xóa bản ghi đó khi tôi xóa sách?
EDIT
Sau khi thay đổi Cascade từ SaveUpdate() để tất cả(), cùng một vấn đề vẫn còn tồn tại nếu tôi cố gắng xóa Sách với một ID của 3. Ngoài ra với Cascade thiết lập để tất cả() , nếu xóa Sách có ID và 1 thì tất cả 3 sách (ID: 1, 2 và 3) sẽ bị xóa để không hoạt động.
Nhìn vào SQL được thực hiện khi phương thức Book.Delete() được gọi khi tôi xóa sách có ID là 3, có vẻ như câu lệnh SELECT đang xem cột sai (mà tôi giả định có nghĩa là SQL DELETE statment sẽ mắc lỗi tương tự, do đó không bao giờ xóa bản ghi đó). Dưới đây là SQL cho RelatedBook
SELECT relatedboo0_.BookId as BookId3_
, relatedboo0_.RelatedBookId as RelatedB2_3_
, book1_.Id as Id14_0_
FROM RelatedBooks relatedboo0_
left outer join [Book] book1_ on relatedboo0_.RelatedBookId=book1_.Id
WHERE relatedboo0_.BookId=3
Các ĐÂU Statment nên tìm một cái gì đó như thế này cho thie trường hợp cụ thể:
WHERE relatedboo0_.RelatedBookId = 3
SOLUTION
Đây là những gì tôi phải làm gì để có được nó hoạt động cho mọi trường hợp
Lập bản đồ:
HasManyToMany(x => x.RelatedBooks)
.ParentKeyColumn("BookId")
.ChildKeyColumn("RelatedBookId")
.Table("RelatedBooks");
Code:
var book = currentSession.Get<Book>(bookId);
if (book != null)
{
//Remove all of the Related Books
book.RelatedBooks.Clear();
//Get all other books that have this book as a related book
var booksWithRelated = currentSession.CreateCriteria<Book>()
.CreateAlias("RelatedBooks", "br")
.Add(Restrictions.Eq("br.Id", book.Id))
.List<Book>();
//Remove this book as a Related Book for all other Books
foreach (var tempBook in booksWithRelated)
{
tempBook.RelatedBooks.Remove(book);
tempBook.Save();
}
//Delete the book
book.Delete();
}
Bạn đang ở trên đi đúng hướng nhưng giải pháp mà sẽ là rất không hiệu quả bởi vì nó tải ALL sách sau đó lọc chúng. Bạn nên tìm ra cách viết lại nó để chỉ trả lại những cuốn sách có sách bị xóa trong bộ sưu tập của họ. Bạn cũng có thể xem xét thực hiện thao tác này thông qua SQL. –
Cảm ơn bạn đã tư vấn. Đã thêm truy vấn tiêu chí NHibernate để chỉ nhận những sách đó. – Jeremy