【问题标题】:NHibernate: deleted object would be re-saved by cascade. Replace object and remove old oneNHibernate:删除的对象将被级联重新保存。替换对象并删除旧对象
【发布时间】:2015-03-08 14:45:49
【问题描述】:

我正在尝试替换 ProgramItem 上的 TimeBlock 对象,然后删除旧的 TimeBlock 对象。这是给我带来问题的删除部分。 我在删除旧的 TimeBlock 对象时遇到了一些“相对”简单的 nHibernate 问题。

例外:
已删除的对象将被级联重新保存(从关联中删除已删除的对象)[*.Model.TimeBlock#15]
15 是 oldTimeBlock 的 Id

我只是尝试了以下几乎所有用法,解决此类问题通常没有任何问题:

oldTimeBlock.ProgramItems = new List<ProgramItem>();
programItem.TimeBlock = null;

以及以任意顺序保存和删除块,并使用 Inverse() 更改映射。
我需要一些新的眼光 - 我怎样才能完成这项工作?

代码:

public class TimeBlock
{
    public virtual int Id { get; set; }
    public virtual IList<ProgramItem> ProgramItems { get; set; }
    ...
}

public class TimeBlockMap : ClassMap<TimeBlock>
{
    public TimeBlockMap()
    {
        Id(x => x.Id);
        HasMany(x => x.ProgramItems).Cascade.SaveUpdate(); // Have tested with Inverse() but seemed to make no difference
    }
}


public class ProgramItem : ImageModel, IIdentifiable
{
    public virtual int Id { get; set; }
    public virtual TimeBlock TimeBlock { get; set; }
    ...
}

public class ProgramItemMap : ClassMap<ProgramItem>
{
    public ProgramItemMap()
    {
        Id(x => x.Id);
        References(x => x.TimeBlock);
    }
}


//Delete old TimeBlock and set new TimeBlock to ProgramItem

var oldTimeBlock = programItem.TimeBlock;

using (var tx = session.BeginTransaction())
{
    oldTimeBlock.ProgramItems = new List<ProgramItem>();
    programItem.TimeBlock = null;
    //session.Save(programItem);
    //session.Save(oldTimeBlock);
    session.Delete(oldTimeBlock);
    tx.Commit(); // location of the exception. If i move the delete oldTimeBlock part below the save programItem part it will still fail in the delete oldTimeBlock part.
}

using (var tx = session.BeginTransaction())
{
    programItem.TimeBlock = timeBlock;
    session.Save(programItem);
    tx.Commit();
}

【问题讨论】:

    标签: c# nhibernate fluent-nhibernate nhibernate-mapping


    【解决方案1】:

    我试着在这里详细解释发生了什么

    我想说,重点就在这里:ProgramItem 被其他集合引用。该集合也被加载到会话中。

    最好的起点是 - 使用 ProgramItem 的任何位置(集合项、参考)将映射更改为 Cascade.None()。然后尝试执行您的删除代码。这会起作用...当然,因为现在级联到位...无法触发该异常。

    下一步 - 开始逐块级联。确保你知道什么是允许的,然后你就会知道哪个引用、集合正在重新保存你的对象。

    我自己的经验/方法是 - 如果您从一个地方删除该项目,如果有级联,也从其他地方明确删除它。这可能具有挑战性,但是...

    【讨论】:

    • 感谢您提供用于识别哪个 Cascade 导致问题的方法。正如你所说,这是另一个参考集合 - 我错过了 - 愚蠢..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 2019-06-30
    • 1970-01-01
    • 2017-09-15
    相关资源
    最近更新 更多