如何调整OData查询仅获取复杂类型的单个属性值?
问题
需求:从复杂类型中检索单个属性值,仅需获取Request.Document.FileInfo.Filename的字符串列表。
使用环境:EF Core 6、OData V4、Windows 11上的Blazor、VS 2022连接MS SQL Express数据库。
简化数据库/实体结构
[Owned] public class FileInfo { [StringLength(255)] public string Filename { get; set; } } public class UserInfo { [StringLength(80)] public string UserID { get; set; } [StringLength(200)] public string Name { get; set; } [StringLength(200)] public string Email { get; set; } } public class Document { [Key] public Guid DocumentID { get; set; } public FileInfo FileInfo { get; set; } [StringLength(80)] public string OwnerID { get; set; } public virtual UserInfo? Owner { get; set; } } public class Request { [Key] public Guid RequestID { get; set; } [StringLength(80)] public string AuthorID { get; set; } [ForeignKey("AuthorID")] public virtual UserInfo? Author { get; set; } public Guid DocumentID { get; set; } [ForeignKey("DocumentID")] public virtual Document? Document { get; set; } }
实体模型配置
public static IEdmModel GetEdmModel() { ODataConventionModelBuilder modelBuilder = new ODataConventionModelBuilder(); modelBuilder.EntitySet<Document>("Documents"); modelBuilder.EntitySet<Request>("Requests"); modelBuilder.ComplexType<FileInfo>(); return modelBuilder.GetEdmModel(); }
现有问题:
- 现有查询返回嵌套结构,包含大量冗余数据
- 使用
$select=时会返回Document的全部属性,无法仅提取目标的Filename字段
解决方案
方法1:使用OData深层字段选择语法
直接在OData查询中指定深层嵌套的属性,结合$expand和$select精准获取目标字段:
GET /odata/Requests?$expand=Document($select=FileInfo)&$select=Document/FileInfo/Filename
部分OData服务支持更简洁的直接深层选择写法:
GET /odata/Requests?$select=Document/FileInfo/Filename
注:确保OData服务启用深层属性选择支持,实体关系映射正确即可,无需额外修改模型配置。
方法2:通过EF Core投影查询自定义返回结果
在后端控制器中自定义查询,直接投影出目标字段,返回纯字符串列表:
[HttpGet] [EnableQuery] public IQueryable<string> GetRequestFilenames() { return _context.Requests .Where(r => /* 你的过滤条件 */) .Select(r => r.Document.FileInfo.Filename); }
在OData模型配置中添加该端点后,前端直接调用即可获取所需数据。
方法3:添加计算属性优化查询(可选)
在Request实体中添加非映射的计算属性,暴露目标字段:
public class Request { // 原有属性... [NotMapped] public string DocumentFilename => Document?.FileInfo?.Filename; }
在模型配置中包含该属性:
modelBuilder.EntityType<Request>().Property(r => r.DocumentFilename);
之后可直接用OData查询该属性:
GET /odata/Requests?$select=DocumentFilename
内容的提问来源于stack exchange,提问作者Razzupaltuff
相关产品推荐
相关产品推荐

