NHibernate:删除的对象将被级联重新保存。替换对象并删除旧对象
NHibernate: deleted object would be re-saved by cascade. Replace object and remove old one
我正在尝试替换 ProgramItem 上的 TimeBlock 对象,然后删除旧的 TimeBlock 对象。这是给我带来问题的删除部分。
我在删除旧的 TimeBlock 对象时遇到一些 'relative' 简单的 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();
}
我试着在这里详细解释发生了什么
- NHibernate Deleted object would be re-saved by cascade
- Delete an item from many-to-many relationship
我想说的是,重点在于:ProgramItem
被其他一些集合引用。该集合也被加载到会话中。
最好的起点是 - 在使用 ProgramItem 的任何地方(收集项、参考)将映射更改为 Cascade.None()
。然后尝试执行您的删除代码。那会起作用...当然,因为现在级联到位...无法触发该异常。
下一步 - 开始逐块级联。确保您知道什么是允许的,然后您就会知道哪个引用、集合正在重新保存您的对象。
我自己的 experience/approach 是 - 如果您从一个地方删除该项目,如果存在级联,则也从其他地方明确删除它。这可能具有挑战性,但是...
我正在尝试替换 ProgramItem 上的 TimeBlock 对象,然后删除旧的 TimeBlock 对象。这是给我带来问题的删除部分。 我在删除旧的 TimeBlock 对象时遇到一些 'relative' 简单的 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();
}
我试着在这里详细解释发生了什么
- NHibernate Deleted object would be re-saved by cascade
- Delete an item from many-to-many relationship
我想说的是,重点在于:ProgramItem
被其他一些集合引用。该集合也被加载到会话中。
最好的起点是 - 在使用 ProgramItem 的任何地方(收集项、参考)将映射更改为 Cascade.None()
。然后尝试执行您的删除代码。那会起作用...当然,因为现在级联到位...无法触发该异常。
下一步 - 开始逐块级联。确保您知道什么是允许的,然后您就会知道哪个引用、集合正在重新保存您的对象。
我自己的 experience/approach 是 - 如果您从一个地方删除该项目,如果存在级联,则也从其他地方明确删除它。这可能具有挑战性,但是...