使用automapper,使用级联删除设置Fluent NHibernate一对多

时间:2011-10-25 17:31:28

标签: nhibernate fluent-nhibernate automapping cascading-deletes

极端的新手问题。我将我的数据库(SQL Server)设置为级联删除我的关系,因此如果删除父实体,所有子项也将被删除(ON DELETE CASCADE)。我希望这能反映在我的自动化Fluent NHibernate设置中。但是,当我尝试删除子实体时,NHibernate会尝试将关系键设置为NULL。

数据库非常简单:( --表示“一个”,-<表示“很多”)

User ---< UserCode >--- Code >--- CodeGroup

当我删除CodeGroup时,删除应该级联到CodeUserCode。当我删除代码时,它应该级联到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 个答案:

答案 0 :(得分:2)

默认情况下,删除不会在NHibernate中级联。在codeGroup.Codes关系上设置级联,如下所示:

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

同样对于你需要受到影响的其他关系。

由OP编辑:最后需要“.Inverse()”。与此问题相关:key-many-to-one and key-property association: nhibernate won't DELETE items from set

答案 1 :(得分:1)

您可能正在点击this issue。除非您运行3.2.0Beta2或更高版本,否则如果您想要级联删除,则必须:

  1. 让孩子的FK可以为空;或
  2. 创建反向关系(即,子项必须具有对父项的映射引用)。
  3. 正如您从票证中看到的那样,这是一个长期(并且受到很多投票)的问题,这个问题最近已得到解决。