从多对多关系中删除项目

时间:2014-12-22 21:31:53

标签: nhibernate fluent-nhibernate many-to-many nhibernate-mapping cascading-deletes

我跟踪两个表之间的映射,它们之间具有多对多关系。如何从映射表中删除条目,在我的情况下是“TB_EMAIL_GRUPO_ARQUIVO”?我只需要从这个“加入”表中删除数据,我不需要从“父表”中删除它。

GrupoModulo

public GrupoModuloMap()
{
    Schema(Const.SCHEMA);
    Table(Const.TB_EMAIL_GRUPO_MODULO);

    CompositeId()
        .KeyReference(x => x.Grupo, Const.ID_GRUPO)
        .KeyReference(x => x.Modulo, Const.ID_MODULO);

    Map(x => x.GrupoId).Column(Const.ID_GRUPO).ReadOnly();
    Map(x => x.ModuloId).Column(Const.ID_MODULO).ReadOnly();

    HasManyToMany(x => x.Arquivos)
        .Table(Const.TB_EMAIL_GRUPO_ARQUIVO)
        .ParentKeyColumns.Add(Const.ID_GRUPO, Const.ID_MODULO)
        .ChildKeyColumn(Const.ID_ARQUIVO)
        .Cascade.SaveUpdate()
        .Not.LazyLoad();
}

ArquivoRetorno

public ArquivoRetornoMap()
{
    Schema(Const.SCHEMA);
    Table(Const.TB_EMAIL_ARQUIVO_RETORNO);

    Id(x => x.Id)
        .Column(Const.ID_ARQUIVO)
        .GeneratedBy.Sequence("SEQ_TB_EMAIL_ARQUIVO_RETORNO")
        .Length(7).CustomSqlType("number(7)")
        .Not.Nullable();

    Map(x => x.Nome)
        .Column("NM_ARQUIVO_RETORNO")
        .Length(50)
        .Not.Nullable();

    References(x => x.Modulo)
        .Column(Const.ID_MODULO)
        .Not.Nullable();

    HasManyToMany(x => x.GrupoModulos)
        .Table(Const.TB_EMAIL_GRUPO_ARQUIVO)
        .ChildKeyColumns.Add(Const.ID_GRUPO, Const.ID_MODULO)
        .ParentKeyColumn(Const.ID_ARQUIVO)
        .Cascade.SaveUpdate()
        .Not.LazyLoad();
}

每当我尝试删除时,我都会收到以下错误:

  

删除的对象将通过级联重新保存(从关联中删除已删除的对象)[Domain.Entity.GrupoModulo#Domain.Entity.GrupoModulo]

有人有任何想法吗?

1 个答案:

答案 0 :(得分:3)

答案是(我确定)NHibernate Deleted object would be re-saved by cascade

让我重新说一下你的情况,会发生什么:

  1. 我们从ArquivoRetorno.GrupoModulos集合中删除 GrupoArquivo
  2. 在该交易,工作单元期间,我们还要加载 GrupoModulo
  3. GrupoModulo已启动 - 现在 - 已加载Arquivos的集合。所以删除 GrupoArquivo 的引用保留在那里
  4. NHibernate必须告知:Deleted object would be re-saved by cascade
  5. 解决方案:

    • 确保GrupoModulo永远不会被加载(保持代理)
    • (我使用的方式) Remove() GrupoArquivo也来自GrupoModulo.Arquivos
    • 或者不要在GrupoArquivo方面使用CASCADE映射:

    使用级联)

    HasManyToMany(x => x.Arquivos)
        .Table(Const.TB_EMAIL_GRUPO_ARQUIVO)
        .ParentKeyColumns.Add(Const.ID_GRUPO, Const.ID_MODULO)
        .ChildKeyColumn(Const.ID_ARQUIVO)
        //.Cascade.SaveUpdate()
        // here
        .Cascade.None()
        .Not.LazyLoad();