NHibernate和自定义SQL子查询(使用临时表)

时间:2013-04-09 01:16:34

标签: nhibernate hql queryover

是否可以将自定义SQL用于子查询“IN”参数。目前,我们成功构建了子查询(subQueryEstate),但它是一个复杂的SQL块,需要时间来处理更大的数据集。使用现有子查询生成查询的代码如下:

session.QueryOver(() => cAlias)
.WithSubquery.WhereProperty(x => x.CPE.ID).In(subQueryEstate)
.JoinAlias(x => x.Costs, () => aCosts, JoinType.LeftOuterJoin)
.JoinAlias(x => x.Open, () => aOpen, JoinType.InnerJoin)
.List();

为了提高执行速度,我们有一个想法,即使用我们将使用ID填充的临时表(事务生命周期)。我们的想法是加入临时表或使用更简单的子查询(SELECT ID FROM TEMP_TABLE)而不是更复杂的原始。

我们可以在NHibernate中使用未映射为子查询的表吗?我们可以编写自定义SQL或创建一个分离的条件来作为参数传递给IN子句吗?我们希望保留NHibernate为查询的其余部分生成正确的SQL这一事实。

理想情况如下:

session.QueryOver(() => cAlias)
.WithSubquery.WhereProperty(x => x.CPE.ID).In("SELECT ID FROM TEMP_TABLE")
.JoinAlias(x => x.Costs, () => aCosts, JoinType.LeftOuterJoin)
.JoinAlias(x => x.Open, () => aOpen, JoinType.InnerJoin)
.List();

思考?想法?可能有一个我们没有想到的更优雅的解决方案。

1 个答案:

答案 0 :(得分:1)

最后我们使用临时表来解决问题。当我们的应用程序使用firebird数据库时,我们创建了四个具有“事务”生命周期的全局临时表。也就是说,临时表中的数据仅在事务的生命周期内有效。

用于创建临时表的SQL(注意我们创建了四个以满足我们的用例)

在提交删除行上创建全局临时表TEMP_TABLE_ID1(ID BIGINT NOT NULL); CREATE INDEX IDX_TEMP_TABLE_ID1 ON TEMP_TABLE_ID1(ID);

使用临时表我们现在可以系统地使用主查询中的ID填充它们。通过使用子查询或连接到临时表来过滤后续查询,这比对每个“下游”查询使用大型子查询要快得多。使用临时表可以显着提高性能,因为表只对事务的生命周期有效,这意味着我们不必担心跨事务污染和/或清除数据表。

一个非常整洁的解决方案。

全球临时表(Firebird) http://www.firebirdsql.org/refdocs/langrefupd21-ddl-table.html

相关问题