NHibernate, при каскадном удалении каскадное удаление строк в связанных таблицах?

Я использовал NHibernate (с сопоставлениями Fluent-NHibernate) в проекте впервые за последние несколько недель, все шло хорошо до сегодняшнего дня, когда я столкнулся с проблемой (скорее всего, моя собственная ошибка).

Я сделал небольшой образец, чтобы проиллюстрировать, чего я пытаюсь достичь:

public class Image
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Path { get; set; }
}

public class FeaturedImage
{
    public virtual int Id { get; set; }
    public virtual Image Image { get; set; }
    public virtual string Description { get; set; }
    public virtual DateTime Date { get; set; }
}

public class ImageMap : ClassMap<Image>
{
    public ImageMap()
    {
        Id(x => x.Id).GeneratedBy.Identity().UnsavedValue(0);
        Map(x => x.Name);
        Map(x => x.Path);
    }
}

public class FeaturedImageMap : ClassMap<FeaturedImage>
{
    public FeaturedImageMap()
    {
        Id(x => x.Id).GeneratedBy.Identity().UnsavedValue(0);
        Map(x => x.Description);
        Map(x => x.Date);
        References(x => x.Image).Not.Nullable().Cascade.Delete();
    }
}

В приведенном выше примере есть несколько изображений, каждый день одно изображение выбирается как «избранное», одно и то же изображение может быть представлено несколько раз. Я бы хотел, чтобы при удалении изображения любые записи FeaturedImage, ссылающиеся на этот идентификатор изображения, автоматически удалялись. Однако на данный момент, если я пытаюсь удалить изображение, которое было показано, оно выдает ошибку:

Оператор DELETE конфликтовал с ограничением REFERENCE "FKF42D8269692640D". Таблица конфликтов «dbo.FeaturedImage», столбец «Image_id».

Если вручную добавить «ON DELETE CASCADE» к ограничению внешнего ключа идентификатора изображения, это сработает:

alter table [FeaturedImage]
 add constraint FKF42D8269692640D foreign key ( Image_id ) references [Image] ON DELETE CASCADE

... но я не уверен, что это рекомендуемый способ сделать это? Если бы кто-нибудь мог посоветовать лучший способ добиться этого, он был бы очень признателен! Заранее спасибо.


person Janine SL    schedule 25.07.2011    source источник


Ответы (1)


Добавленный вами .Cascade.Delete() находится не на той стороне отношения, и это фактически приведет к удалению изображения при удалении FeaturedImage.

То, что вы хотите сделать, можно выполнить, создав коллекцию FeaturedImage в изображении, отобразив ее как обратный мешок с каскадным удалением в ключе.

Я не использую Fluent, но в XML вы устанавливаете on-delete="cascade" в элемент коллекции <key>; ищите что-то похожее.

person Diego Mijelshon    schedule 25.07.2011
comment
Спасибо! Я удалил .Cascade.Delete() из FeaturedImageMap и добавил HasMany(x => x.Featured).Inverse().ForeignKeyCascadeOnDelete().KeyColumn("Image_id"); в ImageMap. Кажется, сейчас работает отлично. - person Janine SL; 25.07.2011