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.
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
- public partial class Flights
- {
- [Key]
- public int Id
- {
- get;
- set;
- }
- public string FlightNumber
- {
- get;
- set;
- }
- public string Name
- {
- get;
- set;
- }
- public string DepartureCityName
- {
- get;
- set;
- }
- public string DestinationCityName
- {
- get;
- set;
- }
- [Singleton]
- public Airport Airport
- {
- get;
- set;
- }
- }
- public partial class Airport
- {
- [Key]
- public int Id
- {
- get;
- set;
- }
- public string Name
- {
- get;
- set;
- }
- public List < Flights > Flights
- {
- get;
- set;
- }
- }
Define EDM model based on the CLR types:
- private static IEdmModel GetEdmModel()
- {
- ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
- builder.Namespace = "WebAPITest";
- builder.ContainerName = "DefaultContainer";
- builder.EntitySet < Flights > ("Flight");
- builder.Singleton < Airport > ("Airport");
- var edmModel = builder.GetEdmModel();
- return edmModel;
- }
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.
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.
- EntitySetConfiguration<Flights>flightsConfiguration = builder.EntitySet<Flights>("Flights");
- flightsConfiguration.HasSingletonBinding(c =>c.Airport, "Airport");
Define Singleton Controller
Singleton controller inherits from the ODataController and name of the controller should be [singletonName]Controller.
- public class AirportController: ODataController
- {
- public static AirportAirport;
- static AirportController()
- {
- InitData();
- }
- private static voidInitData()
- {
- Airport = new Airport()
- {
- Id = 1,
- Name = "Ahmedabad Airport",
- };
- }
- }
We can define as many action methods in Singleton controller that are required. In this example I have defined “GET” method for Singleton controller.
- public IHttpActionResult Get()
- {
- return Ok(Airport);
- }
URL:
http://localhost:24367/Airport 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.