流利的NHibernate自我引用多对多

Jer*_*emy 9 many-to-many fluent-nhibernate self-reference

我有一个名为Books的实体,可以列出更多名为RelatedBooks的书籍.

缩写的Book实体看起来像这样:

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

      public virtual IList<Book> RelatedBooks { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

以下是此关系的映射

HasManyToMany(x => x.RelatedBooks)
                .ParentKeyColumn("BookId")
                .ChildKeyColumn("RelatedBookId")
                .Table("RelatedBooks")
                .Cascade.SaveUpdate();
Run Code Online (Sandbox Code Playgroud)

以下是在RelatedBooks表中生成的数据示例:

BookId     RelatedBookId
1          2
1          3
Run Code Online (Sandbox Code Playgroud)

当我尝试删除一本书时会出现问题.如果我删除ID为1的书,一切正常,并且RelatedBooks表删除了两个相应的记录.但是,如果我尝试删除ID为3的书,我会收到错误"DELETE语句与REFERENCE约束冲突"FK5B54405174BAB605".冲突发生在数据库"Test",表"dbo.RelatedBooks",列'RelatedBookId "".

基本上发生的事情是Book无法删除,因为RelatedBooks表中的RelatedBookId为3的记录永远不会被删除.

删除图书时如何删除该记录?

编辑

将Cascade从SaveUpdate()更改为All()后,如果我尝试删除ID为3的Book,同样的问题仍然存在.同时将Cascade设置为All(),如果删除Book with和ID为1,然后删除所有3本书(ID:1,2和3),这样也无法正常工作.

查看当我删除I​​D为3的Book时调用Book.Delete()方法时执行的SQL,看起来SELECT语句看起来是错误的列(我假设这意味着SQL DELETE语句会犯同样的错误,因此永远不会删除该记录).这是RelatedBook的SQL

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
Run Code Online (Sandbox Code Playgroud)

对于特定情况,WHERE语句应该看起来像这样:

WHERE relatedboo0_.RelatedBookId = 3
Run Code Online (Sandbox Code Playgroud)

以下是我必须要做的就是让它适用于所有情况

制图:

HasManyToMany(x => x.RelatedBooks)
                .ParentKeyColumn("BookId")
                .ChildKeyColumn("RelatedBookId")
                .Table("RelatedBooks");
Run Code Online (Sandbox Code Playgroud)

码:

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();
}
Run Code Online (Sandbox Code Playgroud)

Jam*_*Ide 4

我认为您需要在删除书籍之前简单地清空RelatedBooks 集合,而不是设置级联属性。

book.RelatedBooks.Clear();
session.Delete(book);
Run Code Online (Sandbox Code Playgroud)

级联删除通常不在多对多关系中完成,因为它将删除关系另一端的对象,在本例中是一本书。