Compartir vía


Creación de un singleton en OData v4 con Web API 2.2

por Zoe Luo

Tradicionalmente, solo se podía acceder a una entidad si se encapsulaba dentro de un conjunto de entidades. Pero OData v4 proporciona dos opciones adicionales, Singleton y Contención, ambas compatibles con WebAPI 2.2.

En este tema se muestra cómo definir un singleton en un punto de conexión de OData en Web API 2.2. Para obtener información sobre qué es un singleton y cómo puede beneficiarse de su uso, consulte Uso de un singleton para definir la entidad especial. Para crear un punto de conexión de OData V4 en la Web API, consulte Creación de un punto de conexión de OData v4 mediante ASP.NET Web API 2.2.

Crearemos un singleton en el proyecto de Web API mediante el siguiente modelo de datos:

Data Model

Un singleton denominado Umbrella se definirá en función del tipo Companyy se definirá un conjunto de entidades denominado Employees en función del tipo Employee.

Definir el modelo de datos

  1. Defina los 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. Genere el modelo EDM basado en los 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(); 
    }
    

    Aquí, builder.Singleton<Company>("Umbrella") indica al generador de modelos que cree un singleton denominado Umbrella en el modelo EDM.

    Los metadatos generados tendrán un aspecto similar al siguiente:

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

    En los metadatos, podemos ver que la propiedad de navegación Company del conjunto de entidades Employees está enlazada al singleton Umbrella. El enlace se realiza automáticamente mediante ODataConventionModelBuilder, ya que solo Umbrella tiene el tipoCompany. Si hay alguna ambigüedad en el modelo, puede usar HasSingletonBinding para enlazar explícitamente una propiedad de navegación a un singleton; HasSingletonBinding tiene el mismo efecto que el uso del atributo Singleton en la definición de tipo CLR:

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

Definición del controlador singleton

Al igual que el controlador EntitySet, el controlador singleton hereda de ODataControllery el nombre del controlador singleton debe 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 controlar diferentes tipos de solicitudes, es necesario que las acciones se definan previamente en el controlador. El enrutamiento de atributos está habilitado de forma predeterminada en WebApi 2.2. Por ejemplo, para definir una acción para controlar la consulta Revenue desde el enrutamiento de atributos Company, use lo siguiente:

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

Si no está dispuesto a definir atributos para cada acción, simplemente defina las acciones como las convenciones de enrutamiento de OData. Dado que una clave no es necesaria para consultar un singleton, las acciones definidas en el controlador singleton son ligeramente diferentes de las acciones definidas en el controlador entityset.

Como referencia, las firmas de método para cada definición de acción del controlador singleton se enumeran a continuación.

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

Básicamente, esto es todo lo que necesita hacer en el lado del servicio. El proyecto de ejemplo contiene todo el código de la solución y el cliente de OData que muestra cómo usar singleton. El cliente se compila siguiendo los pasos descritos en Creación de una aplicación cliente de OData v4.

.

Gracias a Leo Hu por el contenido original de este artículo.