Создание singleton в OData версии 4 с помощью веб-API 2.2
Зои Луо
Как правило, доступ к сущности можно было получить только в том случае, если она была инкапсулирована внутри набора сущностей. Но OData версии 4 предоставляет два дополнительных варианта: Singleton и Containment, которые поддерживает WebAPI 2.2.
В этой статье показано, как определить одноэлементную конечную точку OData в веб-API 2.2. Сведения о том, что такое одноэлементный элемент и как его использовать, см. в статье Использование одноэлементного элемента для определения специальной сущности. Сведения о создании конечной точки OData версии 4 в веб-API см. в статье Создание конечной точки OData версии 4 с помощью веб-API ASP.NET 2.2.
Мы создадим одноэлементный объект в проекте веб-API, используя следующую модель данных:
Одноэлементный с именем Umbrella
будет определен на основе типа Company
, а набор сущностей с именем Employees
— на основе типа Employee
.
Определение модели данных
Определите типы СРЕДЫ 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; } }
Создайте модель EDM на основе типов СРЕДЫ CLR.
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")
одноэлементный объект с именемUmbrella
в модели EDM.Созданные метаданные будут выглядеть следующим образом:
<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>
Из метаданных видно, что свойство
Company
навигации в набореEmployees
сущностей привязано к одноэлементнойUmbrella
. Привязка выполняется автоматически с помощьюODataConventionModelBuilder
, так как имеетCompany
толькоUmbrella
тип . Если в модели есть неоднозначность, можно использоватьHasSingletonBinding
для явной привязки свойства навигации к одноэлементному объекту;HasSingletonBinding
имеет тот же эффект, что и использование атрибутаSingleton
в определении типа CLR: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. Например, чтобы определить действие для обработки запросов Revenue
с Company
помощью маршрутизации атрибутов, используйте следующее:
[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, в котором показано, как использовать singleton. Клиент создается путем выполнения действий, описанных в разделе Создание клиентского приложения OData версии 4.
.
Спасибо Лео Ху за оригинальное содержание этой статьи.