First experiments using EF Core with Azure Cosmos DB

Entity Framework Core (EF Core) was designed to not being a framework for only relational databases. It just takes some time to get the first non-relational providers. Now is the time.

Microsoft now has the first preview for an EF Core provider for Cosmos DB. With this I have to do my first experiments using Cosmos DB from EF Core.

Unicorn in galaxy nebula cloud

Azure Cosmos DB

Azure Cosmos DB is a NoSQL database from Microsoft. It is globally distributed and offers multiple models. You can store data with key/values pairs, records with multiple columns (table storage), documents, and data linked within graphs. If you need massive amounts of data, reads, and writes with fast responses and high throughput, Azure Cosmos DB gives you great options.

EF Core Providers

Available EF Core providers are listed in the document Database Providers. The provider I’m using most of the time is of course the provider for SQL Server. There are some other providers as well, e.g. from Microsoft for SQLite, and in-memory. From the Npgsql Development Team you can get a provider for PostreSQL. MySQL and MariaDB providers are from the Pomelo Foundation Project. Erik Ejlskov Jensen created a provider for SQL Server Compact. Oracle offers a provider for MySQL. Jiří Činčura and Rafael Almeida have providers for Firebird. IBM is in the game with providers for Db2 and Informix. Paid high quality providers for Oracle, PostgreSQL, SQLite, and MySQL are from DevArt. There’s even one for Microsoft Access from Bubi.

Missing are Non-SQL providers, and an Oracle provider from Oracle. Oracle already has a Statement of Direction for .NET Core and Entity Framework Core, so a provider from Oracle is coming soon. Oracle is not left out as there’s a provider from DevArt as previously mentioned. Microsoft now has a sample provider for Oracle as well, but this one has some limitations.

With NoSQL Providers, Microsoft started to work on a Azure Table Storage provider. Because of time constraints, this was delayed. Now the Cosmos DB provider has a bigger focus. Preview 1 for Microsoft.EntityFrameworkCore.Cosmos.Sql is now available on the NuGet server.

Project Preparation

To start, I’m creating a .NET Core 2.2 console application and adding these packages:

  • Microsoft.EntityFrameworkCore.Cosmos.Sql
  • Microsoft.Extensions.Configuration.Json
  • Microsoft.Extensions.Configuration.UserSecrets
  • Microsoft.Extensions.DependencyInjection
  • Microsoft.Extensions.Logging.Debug

The configuration for the Cosmos DB is read from a JSON configuration file. I’m not storing the secret key in the source code repository. Instead, app secrets are used during development time with the package Microsoft.Extensions.Configuration.UserSecrets.

The EF Core context is instantiated by using dependency injection, that’s why the package Microsoft.Extensions.DependencyInjection is added. EF Core could be used without creating a DI container. However as in all production apps I’m creating nowadays I’m using a DI container, I’m using it with this small sample as well.

For logging I’m using the ILogger interface, to see what information is traced by the EF Core provider – that’s the reason for the Microsoft.Extensions.Logging.Debug package.

.NET Core 2.2 is in preview at the time of this writing, and can be downloaded from the .NET Core 2.2 downloads.

The project file for the sample app lists the packages:

Creating Azure Cosmos DB

Before building the application, I’m creating a new Azure Cosmos DB account:

Create Azure Cosmos DB Account

Creating an Azure Cosmos DB account, you need to decide and select one of the APIs:

  • SQL
  • MongoDB
  • Cassandra
  • Azure Table
  • Gremlin (graph)

Azure Cosmos DB offers different storage technologies, such as JSON documents, table storage, and storing relations using a graph API. SQL is the successor of DocumentDB, and this is where this new provider can be used.

To access this account from the provider, from the portal the URI and the key is needed. All this information can be accessed by selecting the Keys settings from the portal.

Use Keys and URI

I’m adding the service endpoint from the Azure Cosmos DB account and a database name to the JSON configuration file appsettings.json:

I’m not directly adding the key to the JSON configuration file, but instead use app secrets. Because an identifier for app secrets (UserSecretsId) was added to CosmosDBWithEFCore.csproj, and the NuGet package Microsoft.Extensions.Configuration.UserSecrets was added, the dotnet CLI can be used to configure the authentication key:

dotnet user-secrets set CosmosSettings:AuthKey "add your auth-key from Azure Cosmos DB"

EF Core Context and Model and Services

Next, I’m creating the EF Core context and the model. The model is defined with the Book class and simple properties:

The EF Core BooksContext does not differ to other EF Core contexts that are used with SQL Server:

The class BooksService is used to read and write Book objects. It’s not different to other services using an EF Core context. With the constructor, the BooksContext is injected. This context is used when creating the database, adding new Book objects, and creating a query to read the Book objects:

First I tried to create the database and the collection in the portal. However, I didn’t see how to map the names at first, and documentation was not existing yet. It turned out that creating the database directly from EF Core is already working which helped finding the default database name.

The dependency injection container is configured in the Program class. Having the NuGet package for the EF Core provider for Azure Cosmos DB referenced, allows using the UseCosmosSql extension method. This method needs the configuration for the service endpoint, the key, and the database name. These settings are coming from appsettings.json, and the app secrets.

The Main method just connects everything together. First, the DI container is configured. The BooksService is returned from the container to a) create the database, b) write book records, and to c) query books.

Running the App

Running the app results in creation of the database with the name passed to the UseCosmosSql method, and the collection named Unicorn. You can see this in the Azure Portal.

Azure Cosmos DB database created

If you’ve ever used the command line for EF Core, you know about the Unicorn.

Using the Azure Cosmos DB Data Explorer, you can see all the book objects created.

Azure Cosmos DB Data Explorer

With the collection name, you can change a different default, or assign a collection name for an entity using the ModelBuilder.

Accessing Azure Cosmos DB generated values

A book is represented within Cosmos DB with the properties defined in the model, and some additional properties used by Azure Cosmos DB:

Here’s some information about these values:

  • etag – This is the resource etag, required for optimistic concurrency. This value is changed with every update.
  • id – A unique name with a max length of 255 characters. This value, must be set on insert, and be unique within the database. Using EF Core, it has the same value as specified by the key in the model.
  • rid – This is a system generated hierarchical unique identifier, and used for navigation.
  • ts – The timestamp shows the last update time.
  • self – An addressable url to the document.
  • attachment – Documents can have attachments. This value gives references to attachment resources.

The type of the class is stored with the Discriminator value. Don’t be tempted to use different collections for every type. You can save different types in the same collection. Retrieving objects on the type is fast, this information is indexed. Calculate costs for Azure Cosmos DB per collection.

Using EF Core, you can either add properties to your model to retrieve these values, or create shadow properties in the context definition.

These shadow properties can be retrieved using the Entry method of the DbContext:

Summary

This just have been the first experiments using Azure Cosmos DB using the new EF Core provider. Azure Cosmos DB integrates nicely into EF Core. You’re creating the models and the context as you are used to, and can create the database, write documents, and create queries.
Additional properties such as the etag and self implemented by Azure Cosmos DB do not need to be part of your model, but can be easily retrieved using the shadow properties from EF Core.

Expect more information on EF Core and Azure Cosmos DB to come in the following months.

If you’ve read this far, consider buying me a coffee which helps me staying up longer and writing more articles.

Buy Me A Coffee

More information on EF Core and writing data-driven applications is in my book Professional C# 7 and .NET Core 2.0, and in my Data Programming workshops.

Enjoy learning and programming!

Christian

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.