Настройка Fluent NHibernate один-ко-многим с каскадным удалением с помощью автомпера
Экстремальный вопрос новичка. Моя база данных (SQL Server) настроена на каскадное удаление для моих отношений, поэтому, если вы удаляете родительский объект, все дочерние элементы также удаляются (ON DELETE CASCADE
). Я хочу, чтобы это было отражено в моей автоматической настройке Fluent NHibernate. Однако, когда я пытаюсь удалить дочернюю сущность, NHibernate вместо этого пытается установить ключ отношения в NULL.
База данных очень проста: (--
для одного", -<
для многих")
User ---< UserCode >--- Code >--- CodeGroup
Когда я удаляю CodeGroup
, удаляет должен каскад до Code
а также UserCode
, Когда я удаляю код, он должен просто каскадно UserCode
но оставь CodeGroup
нетронутым.
Мои объекты (свойства удалены для ясности):
public class User {
public virtual IList<Code> FoundCodes { get; private set; }
}
public class Code {
public virtual IList<User> UsersWithCode { get; private set; }
public virtual CodeGroup CodeGroup { get; set; }
}
public class CodeGroup {
public virtual IList<Code> Codes { get; private set; }
}
Вот как выглядит SessionFactory:
var _sessionFactory =
Fluently.Configure()
.Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2005.ConnectionString(c => c.FromConnectionStringWithKey("db")).ShowSql())
.Cache(csb => csb.UseQueryCache())
.Mappings(m =>
m.AutoMappings.Add(
AutoMap.AssemblyOf<Code>(new AutomappingConfiguration())
.Override<User>(map => map.HasManyToMany(u => u.FoundCodes).Table("UserCode"))
.Override<Code>(map => map.HasManyToMany(c => c.UsersWithCode).Inverse().Table("UserCode"))
.Conventions.Add(new CustomForeignKeyConvention())))
.BuildSessionFactory())
Но когда я делаю это:
using (var tx = _db.BeginTransaction())
{
var codeGroup = _db.Load<CodeGroup>(id);
_db.Delete(codeGroup);
tx.Commit();
}
Я получаю это:
could not delete collection: [MidnightRoseRace.Data.Entities.CodeGroup.Codes#8]
[SQL: UPDATE [Code] SET CodeGroupId = null WHERE CodeGroupId = @p0]
Cannot insert the value NULL into column 'CodeGroupId', table 'MyNamespace.dbo.Code';
column does not allow nulls. UPDATE fails.
The statement has been terminated.
Все, что нужно сделать, это удалить, но вместо этого он пытается установить ненулевой внешний ключ на ноль. В чем дело?
2 ответа
Удаления не каскадно по умолчанию в NHibernate. Установить каскадирование codeGroup.Codes
отношения как это:
AutoMap.AssemblyOf<Code>(new AutomappingConfiguration())
// existing overrides
.Override<CodeGroup>(
map => map.HasMany(c => c.Codes).Cascade.AllDeleteOrphan().Inverse())
И аналогично для других отношений, на которые нужно повлиять.
Отредактировано OP: Просто нужно, чтобы ".Inverse()" в конце. Связанный с этим вопросом: связь ключ-многие-к-одному и свойство-ключ: nhibernate не удалит элементы из набора
Возможно, вы решаете эту проблему. Если вы не используете 3.2.0Beta2 или более позднюю версию, если вы хотите каскадно удалять, вы должны либо:
- сделать FK ребенка обнуляемым; или же
- создать обратную связь (то есть дочерний элемент должен иметь сопоставленную ссылку на родительский элемент).
Как вы можете видеть из заявки, это давняя (и очень одобренная) проблема, которая совсем недавно была исправлена.