Criar um singleton no OData v4 usando a API Web 2,2

por Zoe Luo

Tradicionalmente, uma entidade só poderia ser acessada se fosse encapsulada dentro de um conjunto de entidades. Mas o OData v4 fornece duas opções adicionais, singleton e confinamento, que são compatíveis com o WebAPI 2,2.

Este artigo mostra como definir um singleton em um ponto de extremidade OData na API Web 2,2. Para obter informações sobre o que é um singleton e como você pode se beneficiar com o uso dele, consulte usando um singleton para definir sua entidade especial. Para criar um ponto de extremidade do OData v4 na API Web, consulte criar um ponto de extremidade do OData v4 usando ASP.NET Web API 2,2.

Criaremos um singleton em seu projeto de API Web usando o seguinte modelo de dados:

Modelo de dados

Um singleton chamado Umbrella será definido com base no tipo Companye um conjunto de entidades chamado Employees será definido com base no tipo Employee.

A solução usada neste tutorial pode ser baixada do codeplex.

Definir o modelo de dados

  1. Defina os tipos 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. Gere o modelo EDM com base nos tipos 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(); 
    }
    

    Aqui, builder.Singleton<Company>("Umbrella") diz ao construtor de modelos para criar um singleton nomeado Umbrella no modelo EDM.

    Os metadados gerados serão semelhantes ao seguinte:

    <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>
    

    Dos metadados, podemos ver que a propriedade de navegação Company no conjunto de entidades de Employees está associada à Umbrellasingleton. A associação é feita automaticamente pelo ODataConventionModelBuilder, já que somente Umbrella tem o tipo de Company. Se houver qualquer ambiguidade no modelo, você poderá usar HasSingletonBinding para associar explicitamente uma propriedade de navegação a um singleton; HasSingletonBinding tem o mesmo efeito que usar o atributo Singleton na definição de tipo CLR:

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

Definir o controlador singleton

Assim como o controlador de EntitySet, o controlador singleton é herdado de ODataControllere o nome do controlador singleton deve ser [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>()
        };
    } 
}

Para lidar com diferentes tipos de solicitações, é necessário que as ações sejam predefinidas no controlador. O Roteamento de atributos é habilitado por padrão no WebApi 2,2. Por exemplo, para definir uma ação para lidar com a consulta Revenue de Company usando o roteamento de atributos, use o seguinte:

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

Se você não estiver disposto a definir atributos para cada ação, basta definir suas ações seguindo as convenções de roteamento OData. Como uma chave não é necessária para consultar um singleton, as ações definidas no controlador singleton são ligeiramente diferentes das ações definidas no controlador de EntitySet.

Para referência, as assinaturas de método para cada definição de ação no controlador singleton estão listadas abaixo.

// 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()

Basicamente, isso é tudo o que você precisa fazer no lado do serviço. O projeto de exemplo contém todo o código para a solução e o cliente OData que mostra como usar o singleton. O cliente é criado seguindo as etapas em criar um aplicativo cliente do OData v4.

.

Agradecemos ao Leo Hu pelo conteúdo original deste artigo.