使用 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
的實體集。
定義資料模型
定義 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; } }
根據 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 貢獻本文章的原始內容。