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

如何将IQueryable转为Expression<Func>,为NHibernate QueryOver提供投影列表?

NHibernate QueryOver 结合 AutoMapper 实现自动DTO投影方案

直接将Query.ProjectTo得到的IQueryable传入QueryOver的Select方法不可行,因为LINQ Query和QueryOver基于不同的表达式模型,无法直接兼容复用。以下是两种简便的替代方案:

方案一:使用AutoMapper官方QueryOver扩展

AutoMapper提供了专门针对QueryOver的ProjectTo扩展方法,可直接实现和LINQ Query一致的自动投影效果,无需手动编写Select表达式。

示例代码

using(ISession session = SessionFactory.OpenSession())
{
    // 直接通过QueryOver调用AutoMapper的ProjectTo扩展
    IList<MasterDto> listMaster = session.QueryOver<MasterEntity>()
        .ProjectTo<MasterDto>(autoMapperConfig)
        .List<MasterDto>();
}

优势

  • 完全复用已有的AutoMapper配置,DTO修改时自动同步投影字段,无需手动维护Select列表
  • 生成的SQL仅包含DTO所需字段,保证查询性能
  • 支持嵌套DTO、自定义映射规则(只要能转换为NHibernate可解析的SQL表达式)

方案二:自定义通用投影工具类

如果无法使用AutoMapper官方扩展(如版本兼容问题),可以基于AutoMapper的映射配置封装工具类,自动生成QueryOver的ProjectionList。

工具类实现

using AutoMapper;
using NHibernate.Criterion;
using System.Linq.Expressions;

public static class QueryOverProjectionHelper
{
    public static IQueryOver<TEntity, TEntity> ProjectToDto<TEntity, TDto>(this IQueryOver<TEntity, TEntity> queryOver, IMapper mapper)
    {
        var typeMap = mapper.ConfigurationProvider.FindTypeMapFor<TEntity, TDto>();
        var projectionList = Projections.ProjectionList();

        foreach (var propertyMap in typeMap.PropertyMaps)
        {
            // 构建实体属性的表达式
            var entityParam = Expression.Parameter(typeof(TEntity));
            var entityProperty = Expression.Property(entityParam, propertyMap.SourceMember.Name);
            // 添加到投影列表,映射到DTO属性名
            projectionList.Add(Projections.Property(entityProperty), propertyMap.DestinationMember.Name);
        }

        return queryOver.Select(projectionList);
    }
}

使用示例

using(ISession session = SessionFactory.OpenSession())
{
    var mapper = autoMapperConfig.CreateMapper();
    IList<MasterDto> listMaster = session.QueryOver<MasterEntity>()
        .ProjectToDto<MasterEntity, MasterDto>(mapper)
        .List<MasterDto>();
}

注意事项

  • 仅支持基础的属性映射,复杂自定义转换(如内存中处理的转换)可能无法生成对应的SQL,需额外处理
  • 需确保AutoMapper配置中实体与DTO的属性映射关系正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:12:40