在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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM