【问题标题】:NHibernate, Add parent if not exists when adding childNHibernate,添加子时如果不存在则添加父
【发布时间】:2018-04-21 14:59:13
【问题描述】:

我正在使用此代码来确定它是否应该创建父级或父级是否已经存在:

var id = 1;
var parent = Session.Get<Parent>(id);

if (parent == null)
  parent = new Parent();

var child = new Child();

child.Parent = parent;
parent.Children.Add(child);

Session.Save(parent);

现在这似乎效率很低,每次添加孩子时,此方法都会使用 3 个单独的 sql 查询来查询数据库:

  1. 根据 id 获取父级
  2. 插入孩子
  3. 插入/更新父级(取决于父级是否存在)

我能以更好的方式做到这一点吗?

【问题讨论】:

    标签: c# sqlite nhibernate


    【解决方案1】:

    实际上有两种情况。

    在第一种情况下,当我们真的不知道时,如果有提供 id 的父母 - 没有其他办法。这样的解决方案总是需要这么多 sql 语句.. 找出是否有父级,如果没有则插入。

    在第二种情况下,如果我们确实知道在 DB 中有一个父级(提供 id) - 我们可以通过内置支持使其更高效:Load&lt;Parent&gt;(id)

    9.2. Loading an object

    ...Load() 返回一个未初始化的代理对象,并且 在您调用 对象...

    在此处获取更多详细信息:

    NHibernate difference between Query<T>, Get<T> and Load<T>

    【讨论】:

      【解决方案2】:

      鉴于您正在进行常规业务逻辑开发,我不会介意这些查询。

      Get 相当快,因为​​它通常通过主键执行查找,通常是聚集索引(不知道 SQLite)。

      无论如何都需要找到现有的父母。您可以使用Load 推迟实际查询,但根据我的经验,无论如何您都需要父查询。

      可能不需要更新父级。它更新了什么?是否缺少逆映射?

      如果您要为很多记录(不仅仅是一个)做整个事情,您可以考虑其他选项。 (批次、预取、期货等。)

      如果您认为您需要针对此代码进行高度优化的实现,您应该考虑避免使用 ORM 并以普通 SQL 实现它(并重新检查它是否真的会使用更少的查询)。编写面向对象的代码需要在内存中有对象,这有时需要从数据库中获取数据,而这在高度优化的实现中是不需要的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-02
        • 2019-03-12
        • 1970-01-01
        • 2017-06-21
        • 2011-11-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多