Skip to content

Files

Latest commit

 

History

History
164 lines (99 loc) · 6 KB

File metadata and controls

164 lines (99 loc) · 6 KB

十、OData

OData 基础知识

开放数据协议是微软设计的一个网络协议,旨在创建一个新的协议来通过 HTTP 查询和更新数据。OData 是一个 Open 协议,这意味着它有多种实现方法。

ASP.NET 网络应用编程接口内置了对 OData 的支持,因此您可以使用 HTTP 协议和 OData 语法查询您的资源。Visual Studio 2012 更新 2 或微软 ASP.NET 网络应用编程接口 OData NuGet 包添加了对网络应用编程接口的完整支持。

我们现在将构建一个支持 OData 的简单 API。

考虑这个控制器:

  public class PostsController : EntitySetController<Post,int>
  {
      private readonly IPostRepository _repository;

      public PostsController(IPostRepository repository)
      {
          _repository =
  repository;
      }

      public override IQueryable<Post> Get()
      {
          IEnumerable<Post> posts= _repository.GetPosts();
          return posts.AsQueryable();
      }
  }

这个控制器不是继承自通常的ApiController,而是一个EntitySetControllerEntitySetController是继承自ODataController的抽象类,而ODataController继承自ApiController

完整的层次结构是:

图 16:实体控制器层次结构

EntitySetController只是一个专门的ApiController,它有内置的工具来管理 OData 请求和构建 OData 响应。

在前面的例子中,控制器被声明为EntitySetController<Post, int>。这两个通用参数表示该端点公开的实体类型和实体标识的类型。因此,邮政类可能是这样的:

  public class Post
  {
      public int
  Id { get; set;
  }
      public string Title { get; set; }
      public string Author { get; set; }
      public DateTime PublishingDate { get; set; }
  }

然后我们覆盖EntitySetControllerGet方法并实现它,这样它返回的列表就是IQueryable<Post>IQueryable是 OData 控制器所需要的,OData 控制器使用它来添加最终在GET请求中提供的查询。

这不足以使 OData 协议与 Web API 一起工作;我们需要更多的配置。在WebApiConfig类中,我们必须添加以下代码:

  ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
  modelBuilder.EntitySet<Post>("Posts");

  Microsoft.Data.Edm.IEdmModel model =
  modelBuilder.GetEdmModel();
  config.Routes.MapODataRoute("ODataRoute", "odata", model);

  config.EnableQuerySupport();

这段代码创建并配置了 OData 端点,并为 OData 请求定义了新的路由。请注意,新路线不会使用/api路线,而是从MapODataRoute中定义的odata开始。另外需要注意的是,前面案例中的 URI 是区分大小写的,所以正确的 URI 会变成/odata/Posts

如果我们想启用 OData 的查询协议,则EnableQuerySupport命令是必需的。

现在,我们准备启动应用程序并测试 OData 协议:

图 17:获取 OData 端点的简单方法

结果和默认的ApiController没有太大区别。唯一真正的区别是属性odata.metadata,它指定了一个网址,我们可以向它询问关于Post资源的信息。如果我们援引 URI,我们获得:

图 18:资源元数据

XML描述了Post资源,该资源显示属性及其类型,而不是实体的一般信息。

然而,OData 的真正强大之处在于,您可以使用特殊的语法生成请求,该语法使您能够创建复杂的查询来过滤、排序和聚合结果。

让我们从给 URI 增加一个订单条款开始:

/odata/Posts?$orderby=PublishingDate

orderby选项指示 OData 引擎我们想要按发布日期排序的结果。我们不必修改代码,因为 ASP.NET 网络应用编程接口的 OData 模块解析查询字符串,过滤器应用于IQueryable结果。

目前支持的选项有:toporderbyfilterinlinecountskip

排序依据

orderby用于指定结果必须如何排序。默认排序是升序,但是我们可以使用以下语法指定排序类型:

/odata/Posts?$orderby=Author desc

我们还可以组合不同的属性:

/odata/Posts?$orderby=Author,PublishingDate

顶端

/odata/Posts?$top=2

top用于指定要退回的物品数量。对于$top=2,我们是说我们只想要两个元素。

过滤器

/odata/Posts?$filter=Author%20eq%20'ema'

filter用于限制结果(类似于 SQL 中的“where”子句)。在这个例子中,我们请求了作者“ema”的帖子。

filter也可以与布尔和比较运算符一起使用。

表 7: OData 布尔运算符

| 操作员 | 描述 | C#等效 | | 情商 | 平等的 | == | | -不知道 | 不平等 | != | | 大型旅行车的 | 大于 | > | | 通用电气公司 | 大于或等于 | >= | | 它 | 不到 | < | | 务实贸易(Labor Exchange)ˌ低爆速炸药(Low Explosive)ˌ职业介绍所(Labour Exchange) | 小于或等于 | <= | | 和 | 和 | && | | 或者 | 或者 | || |

使用这些运算符,我们可以创建更复杂的查询:

/odata/Posts?$filter=Author%20eq%20'ema'%20and%20Title%20eq%20'post2'

/odata/Posts?$filter=Author%20eq%20'ema'%20or%20Author%20eq%20'tessa'

Inlinecount

inlinecount用于添加集合中项目数量的信息:

/odata/Posts?$inlinecount=allpages

allpages值在 OData 规范中定义,必须包括 URI 标识的集合中实体数量的计数(在应用 URI 上存在的任何$filter系统查询选项后)。

跳跃

Skip用于跳过第一个 n 个值,只返回下一个:

/odata/Posts?$skip=2

在本例中,skip只返回列表中从第三个元素开始的元素。

OData 的能力远不止这些;该协议还规定了修改资源的方式,但细节超出了本书的范围。

总结

OData 是一种有趣的技术,可以用来查询我们的 API。OData 端点不是用各种参数创建许多端点来匹配整个可能的请求,而是用几行代码就解决了大多数问题。在本章中,我们看到了它是如何工作的,以及用于构建查询的基本语法。