ASP .NET MVC 4 WebApi:如何手动处理OData查询?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (18)

我必须使用Web服务取得的WebAPI由ASP .NET MVC提供4.我知道其中的WebAPI自动工作在顶部层处理的OData查询(例如$filter$top$skip),但如果我想自己处理过滤?

我不是简单地从我的数据库返回数据,但我有另一个层添加一些属性,进行一些转换等。所以查询我的所有数据,转换它们并将它们返回到WebAPI类进行OData过滤不仅仅是好足够。这当然非常缓慢,通常是一个糟糕的主意。

那么是否有一种方法可以我的WebAPI入口点的OData查询参数传播到我调用来获取和转换数据的函数?

例如,一个GET可以/api/people?$skip=10&$top=10在服务器上调用:

public IQueryable<Person> get() {
    return PersonService.get(SomethingAboutCurrentRequest.CurrentOData);
}

PersonService

public IQueryable<Person> getPeople(var ODataQueries) {
    IQueryable<ServerSidePerson> serverPeople = from p in dbContext.ServerSidePerson select p;
    // Make the OData queries
    // Skip
    serverPeople = serverPeople.Skip(ODataQueries.Skip);
    // Take
    serverPeople = serverPeople.Take(ODataQueries.Take);
    // And so on
    // ...

    // Then, convert them
    IQueryable<Person> people = Converter.convertPersonList(serverPeople);
    return people;
}
提问于
用户回答回答于

我只是偶然发现了这篇旧文章,并且我添加了这个答案,因为现在它可以很容易地自己处理OData查询。这是一个例子:

[HttpGet]
[ActionName("Example")]
public IEnumerable<Poco> GetExample(ODataQueryOptions<Poco> queryOptions)
{
    var data = new Poco[] { 
        new Poco() { id = 1, name = "one", type = "a" },
        new Poco() { id = 2, name = "two", type = "b" },
        new Poco() { id = 3, name = "three", type = "c" }
    };

    var t = new ODataValidationSettings() { MaxTop = 2 };
    queryOptions.Validate(t);

    //this is the method to filter using the OData framework
    //var s = new ODataQuerySettings() { PageSize = 1 };
    //var results = queryOptions.ApplyTo(data.AsQueryable(), s) as IEnumerable<Poco>;

    //or DIY
    var results = data;
    if (queryOptions.Skip != null) 
        results = results.Skip(queryOptions.Skip.Value);
    if (queryOptions.Top != null)
        results = results.Take(queryOptions.Top.Value);

    return results;
}

public class Poco
{
    public int id { get; set; }
    public string name { get; set; }
    public string type { get; set; }
}
用户回答回答于

来自URL的查询被转换为LINQ表达式树,然后针对您的操作返回的IQueryable执行。可以分析表达式并以任何您想要的方式提供结果。缺点是你需要实现IQueryable,这不是很容易。如果有兴趣,请参阅此博客文章系列:http : //blogs.msdn.com/b/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx。它讨论了WCF数据服务,但Web API使用的过滤器表达式非常相似。

扫码关注云+社区