OData简介
在面向服务的接口开发中,很多时候,没法准确预测到用户需要什么。因此总是要不断地增加新的接口,不断地修改返回的对象。
因此也就产生了一种所谓的资源为导向的架构(ROA),暴露Web服务的资源,并且用户能够对各种对资源进行实时的查询,具有表现数据和整合数据的能力。类似于使用 SQL 在数据库中查询数据。唯一的区别是,ROA你通过URL创建查询。
OData是一个协议,规定公开数据的Web服务的特点。下面这段话是OData的定义
Open Data Protocol (开放数据协议,OData)是用来查询和更新数据的一种Web协议,其提供了把存在于应用程序中的数据暴露出来的方式。OData运用且构建于很多 Web技术之上,比如HTTP、Atom Publishing Protocol(AtomPub)和JSON,提供了从各种应用程序、服务和存储库中访问信息的能力。OData被用来从各种数据源中暴露和访问信息, 这些数据源包括但不限于:关系数据库、文件系统、内容管理系统和传统Web站点。
创建Webapi OData服务项目
下面以最简单的示例说明项目创建过程。
创建Webapi网站项目
添加依赖的nuget package
Install-Package Microsoft.AspNet.Odata
Install-Package EntityFramework
创建数据上下文
public class Product { public int Id { get; set; } public string Name { get; set; } public DateTimeOffset? ReleaseDate { get; set; } public DateTimeOffset? SupportedUntil { get; set; } public virtual ProductFamily Family { get; set; } }
public class ProductsContext : DbContext { static ProductsContext() { Database.SetInitializer(new ProductsContextInitializer()); } public ProductsContext() : base("Products") { //// Remove the following line after fixing https://aspnetwebstack.codeplex.com/workitem/1768 this.Configuration.ProxyCreationEnabled = false; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Product>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); modelBuilder.Entity<ProductFamily>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); modelBuilder.Entity<Supplier>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); base.OnModelCreating(modelBuilder); } public DbSet<Product> Products { get; set; } public DbSet<ProductFamily> ProductFamilies { get; set; } public DbSet<Supplier> Suppliers { get; set; } }
创建接口控制器
public class ProductsController : ODataController { // this example uses EntityFramework CodeFirst ProductsContext _db = new ProductsContext(); /// <summary> /// Adds support for getting products, for example: /// /// GET /Products /// GET /Products?$filter=Name eq 'Windows 95' /// GET /Products? /// /// <remarks> /// Support for $filter, $orderby, $top and $skip is provided by the [EnableQuery] attribute. /// </remarks> /// </summary> /// <returns>An IQueryable with all the products you want it to be possible for clients to reach.</returns> [EnableQuery] public IQueryable<Product> Get() { // If you have any security filters you should apply them before returning then from this method. return _db.Products; } /// <summary> /// Adds support for getting a product by key, for example: /// /// GET /Products(1) /// </summary> /// <param name="key">The key of the Product required</param> /// <returns>The Product</returns> [EnableQuery] public SingleResult<Product> Get([FromODataUri] int key) { return SingleResult.Create(_db.Products.Where(p => p.Id == key)); } ... }
配置链接字符串
<entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"> <parameters> <parameter value="Data Source=.;Initial Catalog=Products;Integrated Security=True;MultipleActiveResultSets=true" /> </parameters> </defaultConnectionFactory> <providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> </providers> </entityFramework>
配置EdmModels
ODataModelBuilder modelBuilder = new ODataConventionModelBuilder(); modelBuilder.EntitySet<Product>("Products"); modelBuilder.EntitySet<ProductFamily>("ProductFamilies"); modelBuilder.EntitySet<Supplier>("Suppliers"); var createProduct = modelBuilder.EntityType<ProductFamily>().Action("CreateProduct"); createProduct.Parameter<string>("Name"); createProduct.Returns<int>(); modelBuilder.Namespace = typeof (ProductFamily).Namespace;
注册OData路由
config.MapODataServiceRoute( routeName: "OData", routePrefix: null, model: ModelBuilder.GetEdmModel());
运行并查看效果
一切都很顺利的实现了。
阅读全文

公众号近期文章
赞赏支持
0 Responses to “OData应用之WebApi”