我有一个类Journal
,其中有一个IList
个对象。
我创建了一个JournalLine
,并意外地通过相同的行生成方法运行了两次。该方法的开始调用Journal
,结束调用_journalLines.Clear()
。所以我有这个顺序:
无行生成_session.SaveOrUpdate(journal)
,调用Journal
。没关系。
生成ID为1,2,3的三个SaveOrUpdate
,添加到JournalLines
并调用Journal._journalLines
呼叫SaveOrUpdate
。此后的断点显示行列表为空。
生成ID为4,5,6的三个Journal._journalLines.Clear()
,添加到JournalLines
并调用Journal._journalLines
。此处的断点显示SaveOrUpdate
包含三项内容。
我剩下一个有6行的_journalLines
。
所有这一切都在一个事务中进行,并且在完成之前,任何数据都不会保留在数据库中。
为什么要合并这两个集合?在我看来,它应该到达最后一个Journal
,其中断点显示它有三行,并将其坚持为三行。其他三个是否仍在内存中徘徊,因为还没有刷新?
编辑:映射
public JournalMap()
{
// Other stuff
HasMany(x => x.JournalLines)
.Access.CamelCaseField(Prefix.Underscore)
.Cascade.AllDeleteOrphan();
}
public JournalLineMap()
{
// Other stuff
References(x => x.Journal);
}
SaveOrUpdate
具有这些:private readonly IList<JournalLine> _journalLines = new List<JournalLine>();
public virtual IEnumerable<JournalLine> JournalLines
{ get { return _journalLines; } }
生成这些行的实际代码太复杂了,无法在此处添加,但是在生成它们后会调用
Journal
,然后调用它,T是_journalLines.Add(journalLine);
public T Add(T entity)
{
_session.SaveOrUpdate(entity);
return entity;
}
如果刷新没有错误,则最终调用
Journal
和_session.Flush()
之前。 最佳答案
此问题可能与日记帐映射的样式有关。通常是用于您的收藏的层叠设置。如果您具有级联设置,例如保存更新或全部设置,例如
<bag name="JournalLines" lazy="true" inverse="true" cascade="save-update"
...
然后发生了什么(使用相似的步骤编号):
...
此时,集合包含项1,2,3 ...
SaveOrUpdate(jurnal)
将进行级联。它还可以进行级联,即会话知道要保留的这三个项目Clear()
将清除IList<>
,但是没有级联触发器可从会话中删除这些项目。目前,我们的前3条JournalLine是真正的孤儿。没有人关心他们...
事务触发的
Flush()
会将所有JournalLines插入数据库解决方案:将映射更改为
cascade="all-delete-orphan"
注意:从上面提供的定义中,我想这就是场景(我刚刚解释了)
如果您呼叫
session.SaveOrUpdate(eachJournalLine)
,则可能是其他问题。在这种情况下,Clear()
是不够的,您还必须迭代所有已删除的项目并将它们与line.Journal = null的关系设置。