Fließendes NHibernate Selbstreferenzieren von vielen zu vielen

Ich habe eine Entität namens "Bücher", die eine Liste weiterer Bücher mit dem Namen "RelatedBooks" enthalten kann.

Die abgekürzte Book-Entität sieht ungefähr so aus:

public class Book
{
      public virtual long Id { get; private set; }

      public virtual IList<Book> RelatedBooks { get; set; }
}

So sieht das Mapping für diese Beziehung aus

HasManyToMany(x => x.RelatedBooks)
                .ParentKeyColumn("BookId")
                .ChildKeyColumn("RelatedBookId")
                .Table("RelatedBooks")
                .Cascade.SaveUpdate();

Hier ist ein Beispiel für die Daten, die dann in der RelatedBooks-Tabelle generiert werden:

BookId     RelatedBookId
1          2
1          3

Das Problem tritt auf, wenn ich versuche, ein Buch zu löschen. Wenn ich das Buch mit der ID 1 lösche, funktioniert alles in Ordnung, und in der RelatedBooks-Tabelle werden die beiden entsprechenden Datensätze entfernt. Wenn ich jedoch versuche, das Buch mit der ID 3 zu löschen, wird der Fehler "Die DELETE-Anweisung ist im Konflikt mit der REFERENCE-Einschränkung" FK5B54405174BAB605 ". Der Konflikt ist in der Datenbank" Test ", Tabelle" dbo.RelatedBooks ", Spalte" RelatedBookId "aufgetreten '".

Grundsätzlich kann das Buch nicht gelöscht werden, da der Datensatz in der RelatedBooks-Tabelle mit der RelatedBookId 3 nie gelöscht wird.

Wie kann ich diesen Datensatz löschen, wenn ich ein Buch lösche?

BEARBEITEN

Nach dem Ändern der Kaskade von SaveUpdate () zu All () besteht das gleiche Problem weiterhin, wenn ich versuche, das Buch mit der ID 3 zu löschen. Auch wenn Cascade auf All () gesetzt ist, wenn das Buch mit der ID 1 gelöscht wird. dann werden alle 3 Bücher (IDs: 1, 2 und 3) gelöscht, so dass auch das nicht funktioniert.

Betrachtet man die SQL, die ausgeführt wird, wenn die Book.Delete () -Methode aufgerufen wird, wenn ich das Buch mit der ID 3 lösche, sieht es so aus, als würde die SELECT-Anweisung die falsche Spalte anzeigen (was meiner Meinung nach bedeutet, dass die SQL-DELETE-Anweisung würde den gleichen Fehler machen, also diesen Datensatz niemals entfernen). Hier ist die SQL für das 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

Die WHERE-Anweisung sollte für diesen speziellen Fall ungefähr so aussehen:

WHERE relatedboo0_.RelatedBookId = 3

LÖSUNG

Hier ist, was ich tun musste, um es für alle Fälle zum Laufen zu bringen

Kartierung:

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();
}