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

如何调整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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 04:35:19