.NET Core API with EF Core and Cosmos

Dan Cokely
5 min readNov 20, 2018

--

“multicolored abstract painting” by Joel Filipe on Unsplash

Intro

In a previous article, I walked through how the preview Cosmos Provider for EF Core could be used to read and write basic documents to and from your Cosmos instance (you can read it here). While it shows EF Core with Cosmos works at a basic level, it doesn't really leave you with a usable setup. This article will expand on that original experiment and build out a .NET Core API that will use EF Core with the Cosmos Provider, to give a bit more realistic idea of how it could be used.

Setup

We are going to re-use the same Cosmos instance as before, so we can take the URI and Primary Key and copy those to use later (If you used an older preview of the Cosmos Provider, you may have an old auto-generated “Unicorn” Collection that was created, sadly they have updated the Cosmos Provider to name the Collection after the context class, instead of “Unicorn”, so that old Collection can stay if you want to keep it).

Next we’ll setup a .NET Core API and then configure it to use EF Core with the Cosmos Provider.

Using Visual Studio 2017 (Im using Community Edition 15.8.9), create a new ASP.NET Core Web project:

Name it whatever you want and select “OK”, next we’ll select to use .NET Core/ ASP.NET Core 2.1 for our API

Now its time to install the NuGet packages, we need the Cosmos Provider and EF Core packages, and we’ll throw in Swashbuckle as well so we can use Swagger to test (not required but helpful for demonstration purposes):

Note we are using the latest preview release (preview 3) of EF Core, but the versions will change frequently as its in preview, you can find a lot of great info about the latest fixes, roadmap updates, and changes in preview 3 here, as well as links to GitHub issue trackers and more.

Basic Setup

We’ll use a standard .NET Core startup class, there are a few key pieces to note: there is an extension method AddDbContext which allows us to add our context class (defined in the next section), and make it available via dependency injection. We’ll also setup Swagger so we can test out our API easily. You will want to swap out the “YourPrimaryKeyHere” with the key from the Cosmos instance, same for the “https://eftest.documents.azure.com:443”, swap it with your instance.

Entities:

This time we are going to have a slightly more complicated set of entities, consisting of 2 separate documents: User, and Car. User will contain an id, name and address, and Car will be an entirely separate document containing an id, make and model.

Our context class looks as follows:

Notice we expose the id field, which Cosmos will automatically add, or we can set it to a Guid ourselves. This is a useful field to identify our entities later.

So we now have our context with our 2 DbSets available to be injected to our controller. Next we’ll make a basic API controller with methods to get/create our CarDocs and UserDocs, as well as lookup a car by make.

Lets run the project and try it out!

I did edit the launchSettings.json to have Swagger be the default launch page by adding the following profile:

Now if we run the project we get our default Swagger page:

The first thing we need to do is run the /api/Values/configure route, which is a bit of a shortcut so we can setup our Cosmos Collection before saving/retrieving anything from it, this route calls _context.Database.EnsureCreated()

This is going to create a Collection for us to save our entities into, you can build the Collection yourself, EF Core has plenty of configuration settings you can manage yourself.

We are starting with an empty collection, so lets try adding a few of each document type first, since we‘ll let Cosmos create our id field, we wont bother with creating it here. We just fill out the fields we care about:

You can see the inserts are working correctly:

We’ll insert a few Car Entities following the exact same steps as above, just using the /api/Values/car route instead.

If we look at Cosmos, we can see the default strategy EF Core is using to store the documents:

Note how EF Core is applying a Discriminator field to our documents with the entity type.

Finally, lets try our GET routes to see if we get back our newly created entities:

Final Thoughts

As you can see there is no security model and no real error handling, and we cheat a little and just return Ok on our POST routes instead of Created and the entity, but the API shows how easily you can quickly spin up an API and data layer using EF core with Cosmos. I think the next interesting test will be trying some performance metrics to see how it stacks up to other solutions out there. If you’re interested in the full working demo, the API project is available on GitHub here.

--

--