У меня есть объект под названием Книги, у которого может быть список других книг, называемых Родственными книгами.
Сокращенная сущность Book выглядит примерно так:
public class Book
{
public virtual long Id { get; private set; }
public virtual IList<Book> RelatedBooks { get; set; }
}
Вот как выглядит отображение для этих отношений
HasManyToMany(x => x.RelatedBooks)
.ParentKeyColumn("BookId")
.ChildKeyColumn("RelatedBookId")
.Table("RelatedBooks")
.Cascade.SaveUpdate();
Вот пример данных, которые затем генерируются в таблице RelatedBooks:
BookId RelatedBookId
1 2
1 3
Проблема возникает, когда я пытаюсь удалить книгу. Если я удаляю книгу с идентификатором 1, все работает нормально, и в таблице RelatedBooks удаляются две соответствующие записи. Однако, если я пытаюсь удалить книгу с идентификатором 3, я получаю сообщение об ошибке «Оператор DELETE конфликтует с ограничением REFERENCE« FK5B54405174BAB605 ». Конфликт произошел в базе данных« Тест », таблица« dbo.RelatedBooks », столбец« RelatedBookId » «».
В основном происходит то, что Книга не может быть удалена, поскольку запись в таблице RelatedBooks, имеющая RelatedBookId, равный 3, никогда не удаляется.
Как получить эту запись для удаления при удалении книги?
EDIT
После изменения Cascade с SaveUpdate () на All (), та же проблема все еще существует, если я пытаюсь удалить Книгу с идентификатором 3. Также с Cascade, установленным на All (), если удалить Книгу с и ID из 1, тогда все 3 книги (идентификаторы: 1, 2 и 3) будут удалены, так что они тоже не будут работать.
Если посмотреть на SQL, который выполняется, когда вызывается метод Book.Delete (), когда я удаляю Книгу с идентификатором 3, похоже, что оператор SELECT смотрит на неправильный столбец (что, как я полагаю, означает, что SQL DELETE statment сделает ту же ошибку, поэтому никогда не удалит эту запись). Вот SQL для 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
В данном конкретном случае устав WHERE должен выглядеть примерно так:
WHERE relatedboo0_.RelatedBookId = 3
РЕШЕНИЕ
Вот что я должен был сделать, чтобы он работал во всех случаях
Отображение:
HasManyToMany(x => x.RelatedBooks)
.ParentKeyColumn("BookId")
.ChildKeyColumn("RelatedBookId")
.Table("RelatedBooks");
Код:
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();
}