OData v4 查询以过滤复杂对象中的结果

OData v4 Query To Filter Results In A Complex Object

我开发了 .NET Core v5 WebAPI 和 Integrated OData v4。 如果我 return 来自我的控制器的正常学生列表并执行 OData 查询,一切正常。

但是我的 API 有一个标准的成功和失败响应结构。一切都只来自数据 属性.

{
    "status": "SUCCESS",
    "data": [
        {
            "name": "Student A",
            "age": 10
        },
        {
            "name": "Student B",
            "age": 11
        },
        {
            "name": "Student C",
            "age": 12
        },
        {
            "name": "Student D",
            "age": 13
        }
    ]
}

fetch Students with age > 11 的 OData URL 查询可以是什么。这是我试过的

https://localhost:44351/api/v2/Students/GetAll?$filter=data/age gt 11

但是它抛出了这个错误

这是我的终点。 此外,我还为搜索、过滤、排序和计数配置了 OData。展开不是我现在考虑的事情

[HttpGet]
[MapToApiVersion("2.0")]
[Route("Success")]
[EnableQuery]
public IActionResult Success20()
{
    var listOfData = new List<Student>();
    listOfData.Add(new Student { Name = "Student A", Age = 10 });
    listOfData.Add(new Student { Name = "Student B", Age = 11 });
    listOfData.Add(new Student { Name = "Student C", Age = 12 });
    listOfData.Add(new Student { Name = "Student D", Age = 13 });
    return Ok(new SuccessResponse<List<Student>>
    {
        Data = listOfData
    });
}

这是我对成功的标准回应

public class Response
{
    protected ResponseStatus ResponseStatus { get; set; }
    public string Status { get; set; }
}

public class SuccessResponse<T> : Response
{
    public T Data { get; set; }

    public SuccessResponse()
    {
        ResponseStatus = ResponseStatus.SUCCESS;
        Status = ResponseStatus.SUCCESS.ToString();
    }
}

根据你的响应结构,我想你在 API 控制器中 returning 一个匿名类型,代码如下,对吗?

    [EnableQuery]
    public IActionResult Get()
    {
        var result = _db.Students.ToList();
        return Ok(new { status = "success", data = result }); 
    }

据我所知,OData 不适用于匿名类型(如果使用上面的代码,它会显示您遇到的错误)。因此,要解决该错误,您可以创建包含 statusdata 的 ResponseModel,然后将其 return 发送给客户端并过滤数据。

这样的代码:

public class ResponseModel
{
    [Key]
    public string status { get; set; }
    public List<Student> data { get; set; }
}

API 控制器:

    [EnableQuery]
    public IActionResult Get()
    {
        var result = _db.Students.ToList();
        //return Ok(new { status = "success", data = result });
        return Ok(new ResponseModel { status="success", data = result});
    }

然后,在GetEdmModel()方法中更改EntitySet模型:

    private static IEdmModel GetEdmModel()
    {
        ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); 
        builder.EntitySet<ResponseModel>("Students"); 
        return builder.GetEdmModel();
    }

之后,我们可以使用url过滤数据:https://localhost:44387/odata/Students?$expand=data($filter= age gt 11)

结果如下:

我找到了解决方案。 原因是排除了 Expand on OData。 我添加了 Expand() 参考@ZhiLv的回答

现在查询正常了。