Быстрый NHibernate сам ссылающийся на многих многим

У меня есть объект под названием Книги, которые могут иметь список большего количества книг под названием RelatedBooks.

Сокращенный Книжный объект смотрит, чему-то нравится это:

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, я добираюсь, ошибка "Оператор удаления конфликтовала со ССЫЛОЧНЫМ ограничением "FK5B54405174BAB605". Конфликт произошел в базе данных "Test", таблица "dbo. RelatedBooks", столбец 'RelatedBookId'".

В основном то, что происходит, является Книгой, не может быть удален, потому что запись в таблице RelatedBooks, которая имеет RelatedBookId 3, никогда не удаляется.

Как я заставляю ту запись быть удаленной, когда я удаляю книгу?

Править

После изменения Каскада от SaveUpdate () ко Всем (), все еще существует та же проблема, если я пытаюсь удалить Книгу с идентификатором 3. Также с Каскадным набором ко Всем (), если удаляют Книгу с и идентификатор 1, то все 3 книги (идентификатор: 1, 2 и 3) удалены так, чтобы не работал также.

Рассмотрение SQL, который выполняется когда Книга. Удалите (), метод называют, когда я удаляю Книгу с идентификатором 3, похоже, что оператор SELECT смотрит на неправильный столбец (который я принимаю средства, что SQL УДАЛЯЕТ 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

ГДЕ statment должен выглядеть примерно так для thie особого случая:

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();
}
9
задан Jeremy 8 February 2010 в 07:14
поделиться

2 ответа

Rather than setting the cascade attribute, I think you need to simply empty the RelatedBooks collection before deleting a book.

book.RelatedBooks.Clear();
session.Delete(book);

Cascading deletes is not typically done in a many-to-many relationship because it will delete the object at the other end of the relationship, in this case a Book.

4
ответ дан 3 November 2019 в 07:47
поделиться
0
ответ дан 3 November 2019 в 07:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: