【问题标题】:NHibernate additional UPDATE query runNHibernate 附加 UPDATE 查询运行
【发布时间】:2010-11-12 12:29:05
【问题描述】:

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

Entity1 包含 Entity2 的列表,相反,Entity2 包含 Entity1 的列表。从这个工作流输出的 SQL 似乎没问题...

  1. 创建 Entity1 和 Entity2 对象
  2. 将 Entity2 添加到 Entity1 的列表中
  3. 调用 session.Save 到 Entity1

-> 对两个实体都运行插入语句,然后将一条记录插入到将它们链接在一起的关联表中。

但是,如果我首先在 Entity2 上调用 session.Save,将其添加到列表中,然后在 Entity1 上调用 session.Save,则会运行额外的 UPDATE 语句,将 Entity2 的所有值设置为与开头插入的内容相同。

虽然没有引起任何问题,但它是一个额外的查询降低性能。我玩过 inverse 属性,但这并不能消除额外的更新语句。目前双方都有 inverse="false" 因为我希望无论保存哪个实体都更新关联表。

有什么想法吗?

【问题讨论】:

    标签: c# nhibernate


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

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

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

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

      虽然有点让我漂亮的 DDD 存储库不太有用!也许存储库应该使用单例会话或类似的东西来避免这个问题?

      谢谢, 约翰

      【讨论】:

      • 请记住会话不是线程安全的。我认为大多数人在 aspnet 中使用 'Session-per-request' 或在应用程序中使用 'session-per-thread'
      • 是的,看看网络上的其他示例,我可能应该实现一个“工作单元”构造来管理可以在打开表单(在我的情况下为富客户端应用程序)并关闭时实例化的会话(释放会话)当表单被释放时。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-27
      相关资源
      最近更新 更多