在ASP.NET Web API中使用OData

一.什么是OData
OData是一个开放的数据协议(Open Data Protocol)
在ASP.NET Web API中,
对于CRUD(create, read, update, and delete)应用比传统WebAPI增长了很大的灵活性
只要正确使用相关的协议,能够在同等状况下
对一个CRUD应用能够节约不少开发时间,从而提升开发效率web

二.怎么搭建数据库

作一个简单的订单查询示例
咱们使用Code First模式建立两个实体对象Product(产品),Supplier(供应商)
1.新建一个ASP.NET Empty项目,选择上使用Web API,以下图
QQ截图20150626152140
2.使用NuGet引用OData和EntityFramework程序集
QQ截图20150626152836
3.在Models文件夹中增长Product(产品),Supplier(供应商)两个实体
api

public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }

        [ForeignKey("Supplier")]
        public int? SupplierId { get; set; }
        public virtual Supplier Supplier { get; set; }
    }
public class Supplier
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public ICollection<Product> Products { get; set; }
    }

4.增长ProductContext数据库上下文对象,而且在web.config中配置好ConnectionString
浏览器

public class ProductContext : DbContext
    {
        public ProductContext()
            : base("Demo")
        { }
        public DbSet<Product> Products { get; set; }
        public DbSet<Supplier> Suppliers { get; set; }
    }

 

<connectionStrings>
        <add name="Demo" connectionString="Data Source=(localdb)\v11.0; 
        Initial Catalog=Demo; Integrated Security=True; MultipleActiveResultSets=True; 
        AttachDbFilename=|DataDirectory|Demo.mdf"
      providerName="System.Data.SqlClient" />
    </connectionStrings>


5.生成数据库
咱们启动程序包管理控制台,运行以下3个命令,
把咱们Code First生成的实体生成到数据库
PM> Enable-Migrations
PM> Add-Migration FirstInit
PM> Update-Database
而后咱们能够在服务器资源管理器中看到咱们生成的数据库表,以下图
QQ截图20150626155543QQ截图20150626155609
6.接下来咱们在WebApiConfig中注册咱们的OData路由
服务器

using Demo2.Models;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
namespace Demo2
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            ODataModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Product>("Products");
            builder.EntitySet<Supplier>("Suppliers");
            config.MapODataServiceRoute("ODataRoute", null, builder.GetEdmModel());
        }
    }
}

7.接下来咱们分别为Product和Supplier新建ODataController,
QQ截图20150626160151
QQ截图20150626160207
咱们在上图中咱们选择好模型类和数据上下文,
并重复上面两步为Supplier实体也生成对应的ODataController
注意:因为VS2013的OData模板中OData V3版本的模板,
引用的名称空间要从V3
using System.Web.Http;
using System.Web.Http.ModelBinding;
using System.Web.Http.OData;
using System.Web.Http.OData.Routing;
修改成V4
using System.Web.Http;
using System.Web.OData;
asp.net

到此,咱们的OData示例程序已经搭建完成,咱们在浏览器里打开这个项目的时候
会出现以下
ide

{
  "@odata.context":"http://localhost:8914/$metadata","value":[
    {
      "name":"Products","kind":"EntitySet","url":"Products"
    },{
      "name":"Suppliers","kind":"EntitySet","url":"Suppliers"
    }
  ]
}

表示已经搭建成功了
函数

三.怎么使用
因为没有测试数据,咱们开始先在数据库表里为Products和Suppliers增长一些测试数据
QQ截图20150626161621
QQ截图20150626161928
接下来咱们看看一些简单的使用示例
在自动生成的ProductsController和SuppliersController中
已经为咱们生成了以下一些Action
QQ截图20150626162339QQ截图20150626162444
因此对于一些增长,修改,删除,更新我就不作过多示例,
这些都是和WebAPI没有什么太多区别,
我主要示例的是查询的使用,不得不说OData已经为咱们把查询功能全作完了
示例1:列出全部Product
URL:http://localhost:8914/Products
测试


{
"@odata.context":"http://localhost:8914/$metadata#Products","value":[
{
"Id":1,"Name":"Products1","Price":100.00,"Category":"Test","SupplierId":1
},{
"Id":2,"Name":"Products2","Price":200.00,"Category":"Test","SupplierId":1
},{
"Id":3,"Name":"Products3","Price":300.00,"Category":"Test","SupplierId":1
},{
"Id":4,"Name":"Products4","Price":400.00,"Category":"P1","SupplierId":2
},{
"Id":5,"Name":"Products5","Price":500.00,"Category":"P1","SupplierId":2
},{
"Id":6,"Name":"Products6","Price":600.00,"Category":"P1","SupplierId":2
},{
"Id":7,"Name":"Products7","Price":700.00,"Category":"P1","SupplierId":2
},{
"Id":8,"Name":"Products8","Price":800.00,"Category":"Test","SupplierId":3
},{
"Id":9,"Name":"Products9","Price":900.00,"Category":"P1","SupplierId":3
}
]
}

示例2,查询单个Products
URL:http://localhost:8914/Products(1) 其中(1)为Idui

{
  "@odata.context":"http://localhost:8914/$metadata#Products/$entity","Id":1,"Name":"Products1","Price":100.00,"Category":"Test","SupplierId":1
}

示例3,查询Products,只列出Name,Price例
URL:http://localhost:8914/Products?$select=Name,Price

{
  "@odata.context":"http://localhost:8914/$metadata#Products(Name,Price)","value":[
    {
      "Name":"Products1","Price":100.00
    },{
      "Name":"Products2","Price":200.00
    },{
      "Name":"Products3","Price":300.00
    },{
      "Name":"Products4","Price":400.00
    },{
      "Name":"Products5","Price":500.00
    },{
      "Name":"Products6","Price":600.00
    },{
      "Name":"Products7","Price":700.00
    },{
      "Name":"Products8","Price":800.00
    },{
      "Name":"Products9","Price":900.00
    }
  ]
}

示例5:只列出ID为1的Products,只显示列Name,Price

URL:http://localhost:8914/Products(1)?$select=Name,Price

{
  "@odata.context":"http://localhost:8914/$metadata#Products(Name,Price)/$entity","Name":"Products1","Price":100.00
}

示例6:列出Products(只有列Name,Price),包括Supplier
URL:http://localhost:8914/Products?$select=Name,Price&$expand=Supplier

{
  "@odata.context":"http://localhost:8914/$metadata#Products(Name,Price,Supplier)","value":[
    {
      "Name":"Products1","Price":100.00,"Supplier":{
        "Id":1,"Name":"Supplier1"
      }
    },{
      "Name":"Products2","Price":200.00,"Supplier":{
        "Id":1,"Name":"Supplier1"
      }
    },{
      "Name":"Products3","Price":300.00,"Supplier":{
        "Id":1,"Name":"Supplier1"
      }
    },{
      "Name":"Products4","Price":400.00,"Supplier":{
        "Id":2,"Name":"Supplier2"
      }
    },{
      "Name":"Products5","Price":500.00,"Supplier":{
        "Id":2,"Name":"Supplier2"
      }
    },{
      "Name":"Products6","Price":600.00,"Supplier":{
        "Id":2,"Name":"Supplier2"
      }
    },{
      "Name":"Products7","Price":700.00,"Supplier":{
        "Id":2,"Name":"Supplier2"
      }
    },{
      "Name":"Products8","Price":800.00,"Supplier":{
        "Id":3,"Name":"Supplier3"
      }
    },{
      "Name":"Products9","Price":900.00,"Supplier":{
        "Id":3,"Name":"Supplier3"
      }
    }
  ]
}

示例7:过滤Products,只显示分类为Test的数据
URL:http://localhost:8914/Products?$filter=Category eq ’Test‘

{
  "@odata.context":"http://localhost:8914/$metadata#Products","value":[
    {
      "Id":1,"Name":"Products1","Price":100.00,"Category":"Test","SupplierId":1
    },{
      "Id":2,"Name":"Products2","Price":200.00,"Category":"Test","SupplierId":1
    },{
      "Id":3,"Name":"Products3","Price":300.00,"Category":"Test","SupplierId":1
    },{
      "Id":8,"Name":"Products8","Price":800.00,"Category":"Test","SupplierId":3
    }
  ]
}

示例8:过滤Products,只显示分类为Test的数据,并排序
URL:http://localhost:8914/Products?$filter=Category eq ’Test‘&$orderby=Price desc

{
  "@odata.context":"http://localhost:8914/$metadata#Products","value":[
    {
      "Id":8,"Name":"Products8","Price":800.00,"Category":"Test","SupplierId":3
    },{
      "Id":3,"Name":"Products3","Price":300.00,"Category":"Test","SupplierId":1
    },{
      "Id":2,"Name":"Products2","Price":200.00,"Category":"Test","SupplierId":1
    },{
      "Id":1,"Name":"Products1","Price":100.00,"Category":"Test","SupplierId":1
    }
  ]
}

下面是$filter的其它的使用方式
1.  http://localhost/Products?$filter=Category eq 'Test'
过滤Category=Test
2.http://localhost/Products?$filter=Price lt 10
过滤Price小于10
3。http://localhost/Products?$filter=Price ge 5 and Price le 15
过滤5<=Price>=15
5,还能够使用数据库函数如:
$filter=substringof('zz',Name)
$filter=year(ReleaseDate) gt 2005

关于排序
$orderby=Price
$orderby=Price desc
$orderby=Category,Price desc

还有一些过滤器如
$skip,$top,$inlinecount等等
因此OData基本上实现咱们们想要查询的相关方法
对于CURD程序的查询来讲大大提升开发效率


四: 相关引用资源
https://www.asp.net/web-api
https://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint

转载请注明出处:http://giantliu.com

相关文章
相关标签/搜索