在这种情况下,NHibernate会尝试两次保存同一个对象吗?

时间:2010-02-25 19:47:45

标签: c# nhibernate persistence

假设我有两个实体:StablePony

Stable有一个IList<Pony>HasMany映射配置为Cascade.All()

这意味着如果我session.Save(myStable),则会保存集合中的每个Pony

但是,如果我这样做会怎么样?

Pony myLittlePony = new Pony(Color.Brown);
Stable myStable = new Stable(WoodTypes.RichMahogany);
myStable.Ponies.Add(myLittlePony);

session.Save(myStable);
session.Save(myLittlePony);

NHibernate会尝试保存myLittlePony 两次吗?或者NHibernate“聪明”到足以知道myLittlePony已经被持久化到数据库了吗?

做这样的事情会对性能产生什么影响吗?

6 个答案:

答案 0 :(得分:2)

NHibernate非常聪明,而AFAIK,因为myLittlePony仍然在会话中并且没有任何更改(IsDirty返回false),它不会触发另一次刷新到持久性媒体。

答案 1 :(得分:2)

当刷新事务时,它可能只被保存一次*但您需要将关系的一侧(通常是集合)标记为反面,以表示关系的非所有者。这将确保行为一致。如果不将集合标记为关系的反面,NH将执行插入操作,然后使用父项中的外键更新子对象。如果存在不可为空的FK约束,这显然会失败。

  • 我的猜测是内部NH会将对象保存两次,但第二次保存不会生成数据库操作,因为该对象在此时没有挂起的更改。

答案 2 :(得分:0)

它应该只保存一次。

实际上,在您提交事务或刷新会话之前,通常没有任何内容进入数据库。

答案 3 :(得分:0)

如果有SQL Server然后运行SQL事件探查器以查看发生了什么,但NHibernate应该只保留该对象。

答案 4 :(得分:0)

。除了告诉会话有关你的新对象*之外,其他任何事情都没有做。 NH只会在会话刷新到数据库时执行该操作,通常是在事务提交时。它永远不会写两次相同的实体。

(*好吧,如果您使用的是错误的身份生成器,它可能会进入数据库)

答案 5 :(得分:0)

我相信你在那里做的事实上是你 需要 做的事情。唯一可以与单个session.Save(myStable);一起使用的方法是,您需要正确配置稳定类的级联关系。