【发布时间】:2010-01-25 14:40:54
【问题描述】:
我们将 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 语句的数量以百万计,这给我们带来了巨大的开销,这直接来自对数据库的所有调用(每个调用都需要“打开数据库会话”、“关闭数据库会话”…… ),即使我们使用的是单个 NHibernate 会话。
我的问题是: 我想以某种方式将所有这些 SELECT 语句合并到一个大的 SELECT 语句中。我们没有运行多线程,也没有在初始化阶段以任何方式更改数据库。
这样做的一种方法是定义我自己的对象并使用 NHibernate 对其进行映射,这将快速加载并在一个查询中加载所有内容,但这需要我们自己实现这些语句中使用的连接操作,并且更糟糕的是 - 破坏了 ORM 抽象。 有没有办法通过一些配置来做到这一点?
谢谢大家!
【问题讨论】:
-
你试过玩批量大小吗?
-
如果你真的是 NHibernate 新手,你可能想看看 nhibernate profiler。
-
NHibernate 不适用于批处理。我对 99% 的查询使用 NHibernate,但对于批处理,ETL 或普通 sql 可能会更好。
标签: database nhibernate orm