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

NHibernate子查询关联表问题:获取最新版本记录的查询实现

QueryOver子查询获取最新版本+关联表解决方案

我看你已经在动手用NHibernate的QueryOver写获取SomeClass最新版本记录的子查询了,刚好写到SelectList的Se...就断了,我来帮你补全这个逻辑,顺便实现关联另一张表的完整查询。

首先先把你的实体类贴出来方便参考:

public class SomeClass {
    public virtual string KeyPart1 { get; set; }
    public virtual string KeyPart2 { get; set; }
    public virtual int VersionNo { get; set; }
    public virtual string ClassProperty1 { get; set; }
    public virtual string ClassProperty2 { get; set; }
}

1. 补全获取最新版本的子查询

你的需求应该是按KeyPart1+KeyPart2这个复合键分组,拿到每组里最大的VersionNo(也就是最新版本),完整的子查询应该是这样:

var subquery = QueryOver.Of<SomeClass>()
    .SelectList(lst => lst
        .SelectGroup(sc => sc.KeyPart1)  // 按KeyPart1分组
        .SelectGroup(sc => sc.KeyPart2)  // 按KeyPart2分组
        .SelectMax(sc => sc.VersionNo)   // 取每组最大的版本号
    );

这个子查询会返回所有复合键对应的最新版本号集合,接下来用它过滤主查询。

2. 关联子查询+关联其他表的完整查询

假设你要关联的表是RelatedClass(比如和SomeClass通过KeyPart1+KeyPart2关联),我们可以用别名来简化关联逻辑:

// 定义查询别名,NHibernate QueryOver推荐用别名来避免歧义
SomeClass scAlias = null;
RelatedClass rcAlias = null;

var mainQuery = session.QueryOver(() => scAlias)
    // 用子查询过滤:只保留复合键和版本号匹配子查询结果的记录
    .WithSubquery.WhereProperty(sc => new { sc.KeyPart1, sc.KeyPart2, sc.VersionNo })
        .In(subquery)
    // 关联另一张表,这里假设关联条件是复合键匹配,你可以根据实际调整
    .JoinAlias(() => scAlias.RelatedClass, () => rcAlias)
    // 如果你需要指定筛选条件,可以在这里加
    .Where(() => rcAlias.IsActive == true)
    // 投影需要的字段,或者直接List<SomeClass>获取实体
    .SelectList(lst => lst
        .Select(sc => sc.ClassProperty1)
        .Select(sc => sc.ClassProperty2)
        .Select(rc => rc.RelatedProperty1)
    );

// 执行查询,结果可以是object[]或者自定义DTO
var results = mainQuery.List<object[]>();

备选:用Exists语法实现更高效的筛选

如果你的数据量较大,用Exists可能比In性能更好,子查询可以这么写:

var existsSubquery = QueryOver.Of<SomeClass>()
    .Where(sc => sc.KeyPart1 == scAlias.KeyPart1)
    .Where(sc => sc.KeyPart2 == scAlias.KeyPart2)
    .SelectMax(sc => sc.VersionNo)
    .Where(sc => sc.VersionNo == scAlias.VersionNo);

var mainQuery = session.QueryOver(() => scAlias)
    .WithSubquery.WhereExists(existsSubquery)
    .JoinAlias(() => scAlias.RelatedClass, () => rcAlias);

这样就能精准拿到每个复合键对应的最新版本记录,同时关联上你需要的其他表了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:09:03