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

.NET 8中使用DTO时OData Expand功能失效的问题求助

问题分析与解决方案

问题核心

改用DTO后,OData的$expand=Student参数无法触发AutoMapper展开关联属性,返回的Student始终为null。手动在ProjectTo中指定包含该属性能正常工作,说明问题在于OData的Expand指令没有传递给AutoMapper的投影配置。

原因

你在CourseDto的AutoMapper映射中使用了ExplicitExpansion():

CreateMap<Course, CourseDto>()
    .ForMember(dest => dest.Student, opt => opt.ExplicitExpansion());

这个配置要求必须显式告诉AutoMapper要展开该属性,才会生成对应的关联查询。但当前流程中,控制器接收到的expand参数没有传递到Mediatr查询处理器,ProjectTo不知道需要展开Student,所以返回null。

解决方案

需要把OData的$expand参数传递给Mediatr查询,再在处理器中把参数解析后传入AutoMapper的ProjectTo配置,让AutoMapper知道要展开哪些属性。

步骤1:修改Mediatr查询,接收Expand参数

public record GetRawCoursesQuery(string? Expand) : IRequest<IQueryable<CourseDto>>;

步骤2:更新查询处理器,解析Expand参数并传递给ProjectTo

public class GetCoursesQueryHandler : IRequestHandler<GetRawCoursesQuery, IQueryable<CourseDto>>
{
    private readonly IApplicationDbContext _context;
    private readonly IMapper _mapper;

    public GetCoursesQueryHandler(IApplicationDbContext context, IMapper mapper)
    {
        _context = context;
        _mapper = mapper;
    }

    public Task<IQueryable<CourseDto>> Handle(GetRawCoursesQuery request, CancellationToken cancellationToken)
    {
        var projectionConfig = new MapperConfiguration(cfg => {});
        if (!string.IsNullOrEmpty(request.Expand))
        {
            // 解析Expand参数,支持多个属性用逗号分隔的情况
            var expandProperties = request.Expand.Split(',', StringSplitOptions.RemoveEmptyEntries)
                .Select(p => p.Trim());
            
            foreach (var prop in expandProperties)
            {
                projectionConfig = projectionConfig.WithExpansion<CourseDto>(dto => dto.GetType().GetProperty(prop));
            }
        }

        var query = _mapper.ProjectTo<CourseDto>(_context.Courses, projectionConfig);
        return Task.FromResult(query);
    }
}

步骤3:调整控制器,传递Expand参数给Mediatr查询

[HttpGet("odata")]
[EnableQuery]
public async Task<IActionResult> GetCoursesAsync(
   [FromQuery] int top,
   [FromQuery] int skip,
   [FromQuery] string orderby,
   [FromQuery] string filter,
   [FromQuery] string expand)
{
    var query = await _sender.Send(new GetRawCoursesQuery(expand));
    return Ok(query);
}

补充说明

  • 如果需要支持多层展开(比如$expand=Student.Courses),需要进一步解析嵌套属性,递归处理每个层级的展开配置。
  • 保留EnableQuery属性,确保筛选、排序、分页等其他OData功能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 21:00:36