我试图在ProgramItem上替换TimeBlock对象,然后删除旧的TimeBlock对象。这是删除部分给我带来的问题。 我有一些相对的'简单的nHibernate问题删除旧的TimeBlock对象。
例外:
删除的对象将通过级联重新保存(从关联中删除已删除的对象)[* .Mode.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();
}
答案 0 :(得分:5)
我试着详细解释这里发生的事情
我想说的是,重点在于:ProgramItem
被其他一些集合引用。该集合也被加载到会话中。
从哪里开始的最佳位置是 - 使用ProgramItem的任何地方(集合项,引用)将映射更改为Cascade.None()
。然后尝试执行删除代码。这将有效...当然,因为现在级联到位......没办法如何触发该异常。
下一步 - 开始逐段级联。确保你知道什么是允许的,然后你就会知道哪个引用,集合正在重新保存你的对象。
我自己的经验/方法是 - 如果您从一个地方删除该项目,如果有级联,则明确地将其从其他地方删除。这可能很有挑战性,但是......