Невозможно каскадно удалять или обновлять в Nhibernate, если несколько сущностей имеют ссылки на один и тот же источник - PullRequest
0 голосов
/ 22 февраля 2012

У меня есть такое отображение ChargeOperations (левая таблица) и Распределения (правая таблица):

Mapping image В сопоставлении кода ChargeOperations выглядит так:

 HasMany(x => x.Distributions).Table("ShadowDistributions").KeyColumn("SourceId").Cascade.All().Inverse();

ShadowDistributions - это правильная таблица. x.Distributions - это просто список Распределений (правая таблица). X - это ChargeOperation (левая таблица)

Отображение распределений (правая таблица)

References(x => x.Source).Nullable().Column("SourceId").Not.LazyLoad();
References(x => x.Dest).Nullable().Column("Dest").LazyLoad().Fetch.Join().Cascade.All();

Итак, я хочу удалить только одну строку из Распределений (правая таблица). И приложения генерируют различные исключения сопоставления, такие как «Транзакция не может быть зафиксирована из-за сбоя ресурса: удаленный объект будет повторно сохранен каскадом (удаляет удаленный объект из ассоциаций) [ChargeOperation # 58]» »или« Неожиданный счетчик строк: 0; ожидается: 1 "и т. д.


Я использую каскад для создания сущностей, и он прекрасно работает, но для удаления мне пришлось
очистите все ссылки в правильной таблице, и после этого сохраните все типы объектов отдельно. Если нет, я получу ошибки.

Но я бы хотел использовать каскадное сохранение. Как я могу это понять?

Возможные варианты после сохранения:

  1. удалил только одну запись из правой таблицы. все записи слева таблица существует
  2. удалил только две записи из правой таблицы. все записи в левой таблице также удаляются

1 Ответ

1 голос
/ 22 февраля 2012

Измените Каскад на Cascade.SaveUpdate(), если вы не хотите удалять ни одну из упомянутых сущностей.

По моему мнению, вам не следует пытаться удалить родителя (ChargeOperations) всякий раз, когда выудалить одного из детей (Distributions)

Пример

public SomeMethod()
{    
    using(ISession session = ... //Get my session from somewhere)
    {
        Distribution childToDelete = ... //Get the distribution to delete
        ChargeOperation parent = ... //Get the parent of the distribution we are deleting

        parent.Distributions.Remove(childToDelete);

        //Since the parent is in session just flush the session to apply changes
        session.Flush();
    }
}
...