我有一个类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的关系设置。

10-04 21:48