2

我有一个类Journal,它有一个IList对象JournalLine

我创建了一个Journal并意外地通过相同的行生成方法运行了两次。此方法的开始调用_journalLines.Clear()和结束调用_session.SaveOrUpdate(journal)。所以我有这个序列:

  1. 生成Journal没有行,调用SaveOrUpdate. 没关系。
  2. 生成JournalLinesID 为 1、2、3 的三个,添加到Journal._journalLines并调用SaveOrUpdate
  3. 打电话Journal._journalLines.Clear()。此后的断点显示行列表为空。
  4. 生成JournalLinesID 为 4、5、6 的三个,添加到Journal._journalLines并调用SaveOrUpdate. 这里的断点显示其中_journalLines包含三件事。
  5. 我剩下一个Journal有 6 行的。

这一切都发生在一个事务中,并且在完成之前没有任何内容保存在数据库中。

为什么要合并这两个集合?在我看来,它应该到达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();如果刷新没有错误。

4

1 回答 1

1

此问题可能与期刊映射的样式有关。主要是用于您的收藏的级联设置。如果您有像save-updateall这样的级联设置,例如

<bag name="JournalLines" lazy="true" inverse="true" cascade="save-update"
 ...

然后发生了什么(使用类似的步骤编号)

  1. ...
  2. 此时,包含项目 1、2、3 ... 的集合SaveOrUpdate(jurnal)将进行级联。它还进行级联,即会话知道要持久化的这 3 个项目
  3. Clear()将清除IList<>但没有级联触发器从会话中删除这些项目。此时,我们的前 3 个 JournalLines 确实是孤儿。没有人关心他们
  4. ...
  5. Flush()由事务触发会将所有 JournalLines 插入 DB

解决方案:将映射更改为

cascade="all-delete-orphan"

注意:根据您在上面提供的定义,我想这是场景(我刚刚解释过)如果您致电session.SaveOrUpdate(eachJournalLine). 在这种情况下Clear()还不够,您还必须迭代所有已删除的项目并将它们的关系设置为 line.Journal = null

于 2013-11-07T07:14:31.140 回答