共用方式為


使用 Web API 2.2 在 OData v4 中建立單一項目

作者:Zoe Luo

傳統上,只有在實體集內封裝實體時,才能存取實體。 但 OData v4 提供兩個額外的選項:單一項目和內含項目,這兩個 WebAPI 2.2 都支援。

本文章說明如何使用 Web API 2.2 在 OData 端點中定義 Singleton。 如需了解單一項目是什麼以及如何使用它的詳細資訊,請參閱使用單一項目來定義您的特殊實體。 若要在 Web API 中建立 OData V4 端點,請參閱使用 ASP.NET Web API 2.2 建立 OData v4 端點

我們將使用下列資料模型,在您的 Web API 專案中建立 singleton:

資料模型

系統會根據類型 Company 定義名為 Umbrella 的單一項目,也會根據類型 Employee 定義名為 Employees 的實體集。

定義資料模型

  1. 定義 CLR 類型。

    /// <summary> 
    /// Present the EntityType "Employee" 
    /// </summary> 
    public class Employee 
    {     
        public int ID { get; set; }     
        public string Name { get; set; }  
       
        [Singleton]     
        public Company Company { get; set; } 
    } 
    /// <summary> 
    /// Present company category, which is an enum type 
    /// </summary> 
    public enum CompanyCategory 
    { 
        IT = 0,     
        Communication = 1,     
        Electronics = 2,     
        Others = 3 
    } 
    /// <summary> 
    /// Present the EntityType "Company" 
    /// </summary> 
    public class Company 
    {
         public int ID { get; set; }
         public string Name { get; set; }
         public Int64 Revenue { get; set; }
         public CompanyCategory Category { get; set; }
         public List<Employee> Employees { get; set; } 
    }
    
  2. 根據 CLR 類型產生 EDM 模型。

    public static IEdmModel GetEdmModel() 
    { 
        ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<Employee>("Employees"); builder.Singleton<Company>("Umbrella");
        builder.Namespace = typeof(Company).Namespace;
        return builder.GetEdmModel(); 
    }
    

    在這裡,builder.Singleton<Company>("Umbrella") 告知模型建立器在 EDM 模型中建立名為 Umbrella 的單一項目。

    產生的中繼資料看起來會像下面這樣:

    <EntityContainer Name="Container"> 
      <EntitySet Name="Employees" EntityType="ODataSingletonSample.Employee"> 
        <NavigationPropertyBinding Path="Company" Target="Umbrella"/> 
      </EntitySet> 
      <Singleton Name="Umbrella" Type="ODataSingletonSample.Company"> 
        <NavigationPropertyBinding Path="Employees" Target="Employees"/> 
      </Singleton> 
    </EntityContainer>
    

    從中繼資料中,我們可以看到 Employees 實體集中的導覽屬性 Company 繫結至單一項目 Umbrella。 繫結是由 ODataConventionModelBuilder 自動完成,因為只有 Umbrella 具有 Company 類型。 如果模型中有任何模棱兩可,您可以使用 HasSingletonBinding 來確實將導覽屬性繫結至單一項目;HasSingletonBinding 效果與在 CLR 類型定義中使用 Singleton 屬性相同:

    EntitySetConfiguration<Employee> employeesConfiguration = 
        builder.EntitySet<Employee>("Employees"); 
    employeesConfiguration.HasSingletonBinding(c => c.Company, "Umbrella");
    

定義單一控制器

如同 EntitySet 控制器,單一控制器承自 ODataController,而單一控制器名稱應該是 [singletonName]Controller

public class UmbrellaController : ODataController 
{
    public static Company Umbrella;
    static UmbrellaController()
    {
        InitData();
    }
    private static void InitData()
    {
        Umbrella = new Company()
        {
            ID = 1,
            Name = "Umbrella",
            Revenue = 1000,
            Category = CompanyCategory.Communication,
            Employees = new List<Employee>()
        };
    } 
}

若要處理不同類型的要求,必須在控制器中預先定義動作。 根據預設,WebApi 2.2 會啟用屬性路由。 例如,若要使用屬性路由定義從 Company 處理查詢 Revenue 的動作,請使用下列:

[ODataRoute("Umbrella/Revenue")] 
public IHttpActionResult GetCompanyRevenue() 
{
     return Ok(Umbrella.Revenue); 
}

如果您不願意為每個動作定義屬性,只要遵循 OData 路由慣例來定義您的動作即可。 由於查詢單一項目不需要金鑰,因此在單一控制器中定義的動作與實體集控制器中定義的動作稍有不同。

如需參考,單一控制器中每個動作定義的方法簽章如下所列。

// Get Singleton 
// ~/singleton 
public IHttpActionResult Get() 
public IHttpActionResult GetUmbrella() 

// Get Singleton 
// ~/singleton/cast 
public IHttpActionResult GetFromSubCompany() 
public IHttpActionResult GetUmbrellaFromSubCompany() 

// Get Singleton Property 
// ~/singleton/property  
public IHttpActionResult GetName() 
public IHttpActionResult GetNameFromCompany() 

// Get Singleton Navigation Property 
// ~/singleton/navigation  
public IHttpActionResult GetEmployees() 
public IHttpActionResult GetEmployeesFromCompany() 

// Update singleton by PUT 
// PUT ~/singleton 
public IHttpActionResult Put(Company newCompany) 
public IHttpActionResult PutUmbrella(Company newCompany) 

// Update singleton by Patch 
// PATCH ~/singleton 
public IHttpActionResult Patch(Delta<Company> item) 
public IHttpActionResult PatchUmbrella(Delta<Company> item) 

// Add navigation link to singleton 
// POST ~/singleton/navigation/$ref 
public IHttpActionResult CreateRef(string navigationProperty, [FromBody] Uri link) 

// Delete navigation link from singleton 
// DELETE ~/singleton/navigation/$ref?$id=~/relatedKey 
public IHttpActionResult DeleteRef(string relatedKey, string navigationProperty) 

// Add a new entity to singleton navigation property 
// POST ~/singleton/navigation 
public IHttpActionResult PostToEmployees([FromBody] Employee employee) 

// Call function bounded to singleton 
// GET ~/singleton/function() 
public IHttpActionResult GetEmployeesCount()

基本上,這是您需要在服務端執行的所有作業。 範例專案包含解決方案的所有程式碼,以及示範如何使用單一項目的 OData 用戶端。 用戶端是依照建立 OData v4 用戶端應用程式步驟來建置的。

.

致謝 Leo Hu 貢獻本文章的原始內容。