NHibernate, "На каскаде удаления", каскадное удаление строк в связанных таблицах? - PullRequest
7 голосов
/ 25 июля 2011

Впервые за последние несколько недель я использовал 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

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

1 Ответ

5 голосов
/ 25 июля 2011

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

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

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

...