database - Consolidating NHibernate open sessions to the DB (耦合 NHibernate 和 DB session )

标签 database nhibernate orm

我们将 NHibernate 用于 ORM,在程序的初始化阶段,我们需要从数据库中加载某个类 T 的许多实例。

在我们的应用程序中,提取所有这些实例的以下代码需要很长时间:

public IList<T> GetAllWithoutTransaction()
{
    using (ISession session = GetSession())
    {
        IList<T> entities = session
            .CreateCriteria(typeof(T))
            .List<T>();
        return entities;
        }
    }
}

使用 NHibernate 日志我发现框架使用的实际 SQL 查询是:

{
    Load a bunch of rows from a few tables in the DB (one SELECT statement).

    for each instance of class T
    {
        Load all the data for this instance of class T from the abovementioned rows 
        (3 SELECT statements).
    }
}

3 个 select 语句是耦合的,即第二个依赖于第一个,第三个依赖于前两个。 如您所见,SELECT 语句的数量以百万计,这给我们带来了巨大的开销,这些开销直接来自对数据库的所有调用(每个调用都需要“打开数据库 session ”、“关闭数据库 session ”…… ),即使我们使用的是单个 NHibernate session 。

我的问题是: 我想以某种方式将所有这些 SELECT 语句合并为一个大的 SELECT 语句。我们没有运行多线程,也没有在初始阶段以任何方式改变数据库。

这样做的一种方法是定义我自己的对象并使用 NHibernate 映射它,这将被快速加载并在一个查询中加载所有内容,但它需要我们自己实现这些语句中使用的连接操作,并且更糟的是 - 破坏了 ORM 抽象。 有没有办法通过一些配置来做到这一点?

谢谢大家!

最佳答案

这被称为 SELECT N+1 problem .您需要决定要放置连接的位置 (FetchMode.Eager)

关于database - Consolidating NHibernate open sessions to the DB (耦合 NHibernate 和 DB session ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2132980/

相关文章:

java - 实现 toString() 时使用反射有意义吗?

android - 升级数据库Sugar ORM总是删除以前表的数据

database - 在 MS Access 中存储数据并在 Excel 中查询

sql - 从一个表中选择列,而在另一个表中该列为 NULL

c# - NHibernate 抛出 'could not resolve property' 异常

nhibernate - 在 PreInsert/PreDelete 事件监听器中保存新实体不会持久保存到数据库

java - H2 - 一般错误 :  "java.lang.NullPointerException" [50000-182]

sql - 如何在 SQL Server Management Studio 中关闭与本地数据库的所有连接?

mysql - NHibernate.ISession.Linq<T>.Where(expression) 检索整个表

java - 在公式标签中创建别名时出错