C# NHibernate附加更新查询运行

C# NHibernate附加更新查询运行,c#,nhibernate,C#,Nhibernate,我使用关联表和cascade=save-update在两个实体之间定义了多对多关系 Entity1包含Entity2的列表,反之,Entity2包含Entity1的列表。从该工作流输出的SQL似乎正常 创建Entity1和Entity2对象 将Entity2添加到Entity1的列表中 呼叫会话。在Entity1上保存 ->对这两个实体运行Insert语句,然后在关联表中插入一条记录,将它们链接在一起 但是,如果我首先在Entity2上调用session.Save,请将其添加到列表中,然后在En

我使用关联表和cascade=save-update在两个实体之间定义了多对多关系

Entity1包含Entity2的列表,反之,Entity2包含Entity1的列表。从该工作流输出的SQL似乎正常

创建Entity1和Entity2对象 将Entity2添加到Entity1的列表中 呼叫会话。在Entity1上保存 ->对这两个实体运行Insert语句,然后在关联表中插入一条记录,将它们链接在一起

但是,如果我首先在Entity2上调用session.Save,请将其添加到列表中,然后在Entity1上调用session.Save,则会运行另一个UPDATE语句,该语句会将Entity2的所有值设置为与开始时插入的值完全相同

虽然不会导致任何问题,但这是一个额外的查询,会降低性能。我已经使用了反向属性,但这并没有消除额外的update语句。目前双方都有inverse=false,因为我希望无论保存哪个实体,关联表都会更新

有什么想法吗?

来自文档: 反转可选-默认为false:如果启用,Hibernate将不会尝试插入或更新此联接定义的属性

我的建议:在某些情况下,为了防止使用双向联接进行额外更新,可能需要更新两个集合:

Contact c;
Address a;    
c.Addresses.Add(a);
a.Contacts.Add(c);

您可能会得到额外的Update语句,因为双方都有inverse=false,并且第一个实体的关系列表保存为空。NH只是在做它认为需要做的事情,以便更新所有的关系。

感谢您的回复,但我相信我已经发现了问题所在。对于实现CRUD操作的每种类型的实体,我都有一个存储库类。每个CRUD操作都启动了自己的会话/事务,称为Save/Update/etc,然后关闭了该事务/会话

如果我调用session.Save for Entity2,则session.Save for Entity1(包含Entity2列表)似乎知道它已经在会话中保留了Entity2,因此不会尝试更新记录

另一方面,如果我调用session.Save for Entity2,那么session.Save for Entity1将在单独的会话/事务中再次更新Entity2。我是NH的新手,所以不确定它如何跟踪哪些对象需要更新,但它必须在会话之间重置

不过,有点让我的DDD存储库没那么有用了!也许存储库应该使用单例会话或类似的方法来避免这个问题

谢谢,
John

请记住,会话不是线程安全的。我认为大多数人在aspnet中使用“每个请求的会话”或在appsYes中使用“每个线程的会话”,看看web上的其他示例,我可能应该实现一个“工作单元”结构来管理会话,在我的情况下,可以在打开表单富客户端应用程序时实例化该会话,并在处理表单时关闭该会话。