Singleton In OData v4 Using Web API

Introduction

Generally, entity can be accessible only when it is encapsulated inside an entity set. OData V4 provides two options to access this entity.

In the previous article, we have learned about Containment. In this article, we will learn what is singleton, how to create singleton in OData.

Singleton is introduced in OData v4 and it allows defining an entity which can be addressed by its name from the service root. The simple definition of singleton is "The element represents a single entity in an entity model is called singleton". Small effort is required for service to support singleton. Singleton is very similar to EntitySet. OData internally use CreateODataEntryWriter for creates singleton and CreateODataFeedWriter used for writing EntitySet. This is biggest difference between singleton and EntitySet.

Example

Airport has many Flights. The following figure shows Entity Relation and we will use this model as data model in this example.

Entity Relation

Here we have two entity sets: Airport and Flights. Airport entity has airport information like id , name and Flights entity have flights information like flight number, departure/destination city name etc. EntitySet may have many entities, but here we have required only entity for airport. Before the release OData v4, we have to define both entities as an EntitySet, So old design forced you to collection of entities even if you required only one entity. Here I am defining Airport entity as singleton. We have two benefits to define Airport as a singleton.

  • We can directly access airport from service root
  • This approach looksvery straightforward because singleton is designed to present a special entity

Define Data Model

  1. public partial class Flights  
  2. {  
  3.     [Key]  
  4.     public int Id  
  5.     {  
  6.         get;  
  7.         set;  
  8.     }  
  9.     public string FlightNumber  
  10.     {  
  11.         get;  
  12.         set;  
  13.     }  
  14.     public string Name  
  15.     {  
  16.         get;  
  17.         set;  
  18.     }  
  19.     public string DepartureCityName  
  20.     {  
  21.         get;  
  22.         set;  
  23.     }  
  24.     public string DestinationCityName  
  25.     {  
  26.         get;  
  27.         set;  
  28.     }  
  29.     [Singleton]  
  30.     public Airport Airport  
  31.     {  
  32.         get;  
  33.         set;  
  34.     }  
  35. }  
  36. public partial class Airport  
  37. {  
  38.     [Key]  
  39.     public int Id  
  40.     {  
  41.         get;  
  42.         set;  
  43.     }  
  44.     public string Name  
  45.     {  
  46.         get;  
  47.         set;  
  48.     }  
  49.     public List < Flights > Flights  
  50.     {  
  51.         get;  
  52.         set;  
  53.     }  
  54. }  
Define EDM model based on the CLR types:
  1. private static IEdmModel GetEdmModel()  
  2. {  
  3.     ODataConventionModelBuilder builder = new ODataConventionModelBuilder();  
  4.     builder.Namespace = "WebAPITest";  
  5.     builder.ContainerName = "DefaultContainer";  
  6.     builder.EntitySet < Flights > ("Flight");  
  7.     builder.Singleton < Airport > ("Airport");  
  8.     var edmModel = builder.GetEdmModel();  
  9.     return edmModel;  
  10. }  
In above code, "builder.Singleton<Airport> ("Airport")" Code tells the model builder to create singleton entity for Airport with name Airport. Below figure shows the Meta of the service.

builder.Singleton

From the Meta of the service, we can see that the navigation property Airport in the Flights entity set is bound to the singleton "Airport" property.NavigationSourceConfiguration class has method called HasSingletonBinding can also be used to bind navigation property to singleton. This has same effect as using Singleton attribute.
  1. EntitySetConfiguration<Flights>flightsConfiguration = builder.EntitySet<Flights>("Flights");  
  2. flightsConfiguration.HasSingletonBinding(c =>c.Airport, "Airport");  
Define Singleton Controller

Singleton controller inherits from the ODataController and name of the controller should be [singletonName]Controller.
  1. public class AirportController: ODataController  
  2. {  
  3.     public static AirportAirport;  
  4.     static AirportController()  
  5.     {  
  6.         InitData();  
  7.     }  
  8.     private static voidInitData()  
  9.     {  
  10.         Airport = new Airport()  
  11.         {  
  12.             Id = 1,  
  13.             Name = "Ahmedabad Airport",  
  14.         };  
  15.     }  
  16. }  
We can define as many action methods in Singleton controller that are required. In this example I have defined “GET” method for Singleton controller.
  1. public IHttpActionResult Get()  
  2. {  
  3.    return Ok(Airport);  
  4. }  
URL: http://localhost:24367/Airport

Output

Output

Same as GET method we can define action methods that we required. Above describe way, we can create singleton property with OData V4 in ASP.net Wen API.


Similar Articles