MedallionOData is a lightweight, zero-setup .NET library for creating and querying OData and OData-like services.
Download the NuGet package (Release notes)
Keep reading for a quick introduction to the library. For a more detailed walkthrough, check out this tutorial.
var context = new ODataQueryContext();
var categories = context.Query(@"http://services.odata.org/v3/odata/odata.svc/Categories");
var foodCategoryId = categories.Where(c => c.Get<string>("Name") == "Food")
.Select(c => c.Get<int>("ID"))
// hits http://services.odata.org/v3/odata/odata.svc/Categories?$format=json&$filter=Name eq 'Food'&$select=ID
.Single();
Console.WriteLine(foodCategoryId); // 0
// we can also perform a more "strongly typed" query using a POCO class
class Category {
public int ID { get; set; }
public string Name { get; set; }
}
var categories2 = context.Query<Category>(@"http://services.odata.org/v3/odata/odata.svc/Categories");
var foodCategoryId2 = categories2.Where(c => c.Name == "Food")
.Select(c => c.ID)
.Single(); // 0
In many cases, you might need to inject custom logic in order to authenticate yourself with a service or otherwise customize the underlying HTTP request. To do this, pass a custom request function to the ODataQueryContext
:
var client = new HttpClient();
// customize client
var context = new ODataQueryContext(async url =>
{
var response = await client.GetAsync(url);
});
return await response.Content.ReadAsStreamAsync();
The example uses EntityFramework and .NET MVC, but the MedallionOData library doesn't depend on either.
private static readonly ODataService service = new ODataService();
[Route("Categories")] // any form of mapping the route will do
public ActionResult Categories()
{
using (var db = new MyDbContext())
{
IQueryable<Category> query = db.Categories;
var result = service.Execute(query, HttpUtility.ParseQueryString(this.Request.Url.Query));
return this.Content(result.Results.ToString(), "application/json");
}
}
While the typical use-case for OData is to have the shape of the data known at compile time, it is sometimes helpful to be able to build services in a way that allows the schema to be dynamic. MedallionOData supports this use-case. See this walkthrough for more details.
SqlServerSyntax
with Microsoft.Data.SqlClient