Настройка Fluent NHibernate один-ко-многим с каскадным удалением с помощью автомпера - PullRequest
1 голос
/ 25 октября 2011

Экстремальный вопрос новичка.Моя база данных (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.

Все, что нужно сделать, это удалить, но вместо этого он пытаетсяустановить ненулевой внешний ключ в null.Что происходит?

Ответы [ 2 ]

2 голосов
/ 25 октября 2011

Удаляет не каскад по умолчанию в NHibernate.Установите каскадное отношение codeGroup.Codes следующим образом:

AutoMap.AssemblyOf<Code>(new AutomappingConfiguration())
    // existing overrides
    .Override<CodeGroup>(
        map => map.HasMany(c => c.Codes).Cascade.AllDeleteOrphan().Inverse())

И аналогично для других отношений, на которые вы должны повлиять.

Отредактировано OP: Просто нужно, чтобы«.Inverse ()» в конце.Связанный с этим вопросом: связь ключ-многие-к-одному и свойство ключа: nhibernate не удалит элементы из набора

1 голос
/ 26 октября 2011

Возможно, вы нажимаете эту проблему .Если вы не используете 3.2.0Beta2 или более позднюю версию, если вы хотите каскадно удалять, вы должны либо:

  1. сделать FK ребенка обнуляемым;или
  2. создать обратную связь (т. е. у ребенка должна быть сопоставленная ссылка на родителя).

Как видно из тикета, это было давно (и оченьupvoted) проблема, которая была совсем недавно исправлена.

...