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

将OData Filter转换为IQueryable表达式时遇属性查找错误求助

问题解决:OData筛选时出现"Could not find a property named 'Id' on type 'Edm.Int32'"错误

类层次结构

public class Company
{
   public ICollection<CompanyType> CompanyTypes { get; set; } = new List<CompanyType>();
}

public class CompanyType
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;

    public static implicit operator int(CompanyType companyType) => companyType.Id;
}

控制器方法

public async Task<ActionResult<CompaniesResponse>> GetCompanies(ODataQueryOptions<GetCompaniesRequestV2> request) {  }

目标实现代码

Task<ActionResult<CompaniesResponse>> GetCompanies(ODataQueryOptions<GetCompaniesRequestV2> request)
{
var expression = // 从查询中提取表达式
var query = new Query(request, expression);
var result = await _mediator.Send(query);
}

错误场景

执行OData查询 $filter=CompanyTypes/any(s: s/Id eq 1)&$skip=0&$top=2 时,抛出错误:

Could not find a property named 'Id' on type 'Edm.Int32'

已尝试的无效代码

//ODataQueryOptions<GetCompaniesRequestV2> request
...

IQueryable queryable = Enumerable.Empty<Company>().AsQueryable();
queryable = request.Filter.ApplyTo(queryable, new ODataQuerySettings());

问题原因

CompanyType类中定义了隐式转换为int类型的操作符,OData构建EDM模型时会自动将CompanyType识别为Edm.Int32类型,而非包含Id、Name属性的复杂/实体类型。这导致筛选条件中访问s/Id时,OData认为当前类型是int,不存在Id属性,进而抛出错误。

解决步骤

1. 显式配置OData EDM模型

在OData模型配置中,手动将CompanyType注册为复杂类型或实体类型,覆盖隐式转换带来的自动识别:

public IEdmModel GetEdmModel()
{
    ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
    // 注册Company实体
    builder.EntitySet<Company>("Companies");
    // 若无需主键,注册为复杂类型
    builder.ComplexType<CompanyType>();
    // 若需将CompanyType作为实体(含主键),则使用:
    // builder.EntityType<CompanyType>().HasKey(ct => ct.Id);
    
    return builder.GetEdmModel();
}

2. 匹配ODataQueryOptions泛型参数

控制器方法中使用的ODataQueryOptions<GetCompaniesRequestV2>,需确保GetCompaniesRequestV2的属性结构与Company完全一致;或业务允许的话,直接使用ODataQueryOptions<Company>,避免模型不匹配导致的解析错误。

3. 正确提取筛选表达式

若需将OData筛选转换为表达式树,针对Company类型处理:

// 假设request为ODataQueryOptions<Company>
var filterExpression = request.Filter?.ApplyTo(
    Enumerable.Empty<Company>().AsQueryable(), 
    new ODataQuerySettings()
).Expression as Expression<Func<Company, bool>>;

内容的提问来源于stack exchange,提问作者w.johnny

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 16:29:56