介尘部落

文学|音乐|休闲娱乐|计算机技术|地球科学|社会学——知识成就命运


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());

运行并查看效果

%image_alt%

一切都很顺利的实现了。

阅读全文
公众号-介尘阅读时光
赞赏支持

0 Responses to “OData应用之WebApi”

Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

×