You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将原生SQLQuery(session.CreateSqlQuery)作为子查询在QueryOver中过滤

如何在NHibernate的QueryOver中使用原生SQL子查询作为IN过滤条件

我来帮你搞定这个问题——你现在的代码直接把CreateSQLQuery实例传给IsIn是行不通的,因为IsIn接收的是内存中的值集合,而不是子查询对象。要把原生SQL查询作为子查询嵌入到QueryOver的IN条件里,需要做两个关键调整,下面是具体的解决方案:

修正后的完整代码

// 1. 将原生SQL查询转换为可作为子查询的DetachedSQLQuery
var idSubquery = _session.CreateSQLQuery(
        "select Id from [dbo].[SomeFunction](:parameter)")
    .AddScalar("Id", NHibernateUtil.Int64) // 仅映射需要的Id列,比AddEntity更高效
    .SetParameter("parameter", folderId)
    .DetachedCriteria; // 转换为分离查询,供QueryOver作为子查询使用

// 2. 在QueryOver中使用IsInSubquery引用子查询
MyEntity entityAlias = null;
var listOfEntities = await _session.QueryOver(() => entityAlias)
    .WhereRestrictionOn(() => entityAlias.Id)
        .IsInSubquery(idSubquery) // 用IsInSubquery替代IsIn,传入子查询对象
    .OrderBy(() => entityAlias.Name).Asc
    .ListAsync(cancelToken).ConfigureAwait(false);

关键调整说明

  • 用AddScalar替代AddEntity:因为我们只需要子查询返回的Id列,不需要把结果映射成完整的long实体,AddScalar可以直接指定列名和数据类型,更轻量高效。
  • 转换为DetachedSQLQuery:调用.DetachedCriteria方法可以把普通的SQLQuery转换成NHibernate能识别的分离子查询对象,这样才能被QueryOver嵌入到最终生成的SQL中。
  • 使用IsInSubquery方法:这是QueryOver中处理子查询IN条件的正确API,IsIn方法是用来传入内存中的值列表(比如List<long>)的,而IsInSubquery才接受子查询对象。

这样调整后,NHibernate会自动把你的原生SQL子查询嵌入到最终的SELECT语句的IN子句中,完美实现你想要的过滤效果~

内容的提问来源于stack exchange,提问作者Baloo0ch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:57:26