在ASP.NET Web API中使用OData

一.什麼是OData
OData是一個開放的數據協議(Open Data Protocol)
在ASP.NET Web API中,
對於CRUD(create, read, update, and delete)應用比傳統WebAPI增加了很大的靈活性
只要正確使用相關的協議,可以在同等情況下
對一個CRUD應用可以節約很多開發時間,從而提高開發效率

二.怎麼搭建

做一個簡單的訂單查詢示例
我們使用Code First模式創建兩個實體對象Product(產品),Supplier(供應商)
1.新建一個ASP.NET Empty項目,選擇上使用Web API,如下圖
QQ截圖20150626152140
2.使用NuGet引用OData和EntityFramework程序集
QQ截圖20150626152836
3.在Models文件夾中增加Product(產品),Supplier(供應商)兩個實體

public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }
    [ForeignKey(</span><span style="color: #800000">"</span><span style="color: #800000">Supplier</span><span style="color: #800000">"</span><span style="color: #000000">)]
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span>? SupplierId { <span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span><span style="color: #000000">; }
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">virtual</span> Supplier Supplier { <span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span><span style="color: #000000">; }
}

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;

到此,我們的OData示例程序已經搭建完成,我們在瀏覽器裏打開這個項目的時候
會出現如下

{
  "@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)爲Id

{
  "@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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章