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

C# 在这种情况下,NHibernate会尝试保存同一对象两次吗?,c#,nhibernate,persistence,C#,Nhibernate,Persistence,假设我有两个实体:稳定的,和小马 Stable有一个IList和一个HasMany映射,映射配置为Cascade.All() 这意味着如果我执行session.Save(myStable),集合中的每一匹小马都将被保存 但是,如果我这样做会发生什么 Pony myLittlePony = new Pony(Color.Brown); Stable myStable = new Stable(WoodTypes.RichMahogany); myStable.Ponies.Add(myLittle

假设我有两个实体:
稳定的
,和
小马

Stable
有一个
IList
和一个
HasMany
映射,映射配置为
Cascade.All()

这意味着如果我执行
session.Save(myStable)
,集合中的每一匹
小马都将被保存

但是,如果我这样做会发生什么

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
已经被持久化到数据库了吗


这样做对性能有什么影响吗?

NHibernate非常聪明,而且顺便说一句,因为myLittlePony仍然在会话中并且没有任何更改(IsDirty返回false),它不会触发对持久性介质的另一次刷新。

它应该只保存一次


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

如果有SQL Server,则运行SQL Profiler以查看发生了什么,但NHibernate应该只保留该对象。

.Save()只会告诉会话有关新对象的信息*。NH只计算会话刷新到数据库时要做什么,通常是在事务提交时。它永远不会写入同一实体两次


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

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

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

    • 我相信你在那里所做的实际上是你需要做的。唯一能与单个
      session.Save(myStable)一起工作的方法
      您需要正确配置稳定类的级联关系。

      我提到稳定类的级联关系是cascade.All()。我没有注意到这一点,建议将其转换为代码块,以使其更引人注目。完成。希望人们将来能看到它=]