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