.NET Framework 4.5.1旧版NHibernate查询改造求助
解决方案
问题原因
你之前的代码报错是因为子查询中直接引用主查询的别名commandAlias无法被NHibernate 3.1正确解析,需要通过Restrictions.EqProperty显式关联主查询与子查询的字段,才能生成正确的关联SQL。
改造后的完整代码
Command commandAlias = null; Payment paymentAlias = null; // 主查询基础条件 var query = session.QueryOver<Command>(() => commandAlias) .Where(x => x.IssueDate >= startOfPeriod && x.IssueDate <= endOfPeriod) .Where(x => x.CommandStatus != CommandStatus.Revoked && x.CommandStatus != CommandStatus.Payed); // 子查询1:计算当前Command的支付总额 var sumPaymentSubquery = QueryOver.Of<Payment>(() => paymentAlias) .Where(Restrictions.EqProperty( Projections.Property(() => paymentAlias.Command.RowId), Projections.Property(() => commandAlias.RowId) )) .Select(Projections.Sum<Payment>(p => p.PaidAmount)); // 子查询2:判断当前Command是否存在关联Payment记录 var existsPaymentSubquery = QueryOver.Of<Payment>(() => paymentAlias) .Where(Restrictions.EqProperty( Projections.Property(() => paymentAlias.Command.RowId), Projections.Property(() => commandAlias.RowId) )) .Select(p => p.RowId); // 组合条件:无关联Payment OR 支付总额小于Command金额 var disjunction = Restrictions.Disjunction() // 无关联Payment记录的情况 .Add(Subqueries.WhereNotExists(existsPaymentSubquery)) // 支付总额小于Command金额(用Coalesce处理无Payment时Sum返回null的情况,转为0) .Add(Restrictions.GtProperty( Projections.Property(() => commandAlias.Amount), Projections.Coalesce(sumPaymentSubquery, 0m) )); // 执行最终查询 var data = query .Where(disjunction) .Fetch(x => x.DepartmentFrom).Eager .Fetch(x => x.FinalizedCommitment).Eager .Fetch(x => x.FinalizedCommitment.Kae).Eager .List();
关键说明
- 关联主查询与子查询:使用
Restrictions.EqProperty替代直接的==比较,让NHibernate能正确识别主查询和子查询的关联关系,避免别名解析错误。 - 处理空值情况:用
Projections.Coalesce将无支付记录时的Sum空值转为0,确保“支付总额小于Command金额”的比较逻辑正常执行。 - 条件组合:通过
Restrictions.Disjunction实现“或”逻辑,同时覆盖“无支付记录”和“支付金额不足”两种业务场景。
内容的提问来源于stack exchange,提问作者Φωτεινή Βέρδου
相关产品推荐
相关产品推荐

