.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
相关产品推荐
相关产品推荐

