/ Azure

Getting Started: EF Core + Cosmos Db

I was really looking forward to having the Cosmos Db provider for Entity Framework Core. So much that I actually submitted a talk for NDC Sydney about how to get started with it even before the provider was out, and it's finally out, still in preview so a lot of things might change, but I'm very excited all the same.

As always, the source code covered in this post is available here

Let's see how to put it together.

Creating an instance of Cosmos Db + Database

In the Azure Portal, you're going to look for Cosmos DB. Just make sure you select the SQL Api when creating it as this is the one supported by EF Core.
step2

Once the instance is created is time to create a new database
step3

This is the database name we're going to use in our application, so save it.
step4

And the collection is like a table in SQL, this is going to line up with a repository (DbSet)
step5

Now give a name to your collection, but be very careful with the throughput.
step6

WARNING!!! You can pay a lot of money if you're careless about the throughput. There's even a check box for you to acknowledge if you set a high value. With the value below, you're looking to pay $11,520.00/month. That's crazy!!!
step7

You're all set from here!
step8

We just need some keys to configure our application
step9

Bringing in the provider

You can do either via the command line which would be dotnet add package Microsoft.EntityFrameworkCore.Cosmos.Sql --version 2.2.0-preview1-35029 or you can use the Visual Studio Package Manager as bellow. There were only 72 downloads at the time. Wow!!!! Is that a good thing (I'm one of the 72 crazy people in the world) or that's a sign I'm going to be in trouble if I try it in production??? :D
step1

Setting up in the project

In my application, I've created a appsettings.json so I can bring the configuration in:

{
  "CosmosDb": {
    "EndpointUrl": "<URI IN THE KEYS SECTION>",
    "PrivateKey": "<PRIMARY OR SECONDARY KEY IN THE KEYS SECTION>",
    "DbName": "<NAME OF THE DATABASE>"
  }
}

In my dependency injection configuration method (if you're creating a Web Api or MVC app, that would potentially be in the startup.cs), I'm going to hook things up.

public static IContainer IocConfig()
{
    ...

    serviceCollection.AddEntityFrameworkCosmosSql();
    serviceCollection.AddDbContext<BlogDbContext>(options =>
    {
        options.UseCosmosSql(
            new Uri(Configuration["CosmosDb:EndpointUrl"]),
            Configuration["CosmosDb:PrivateKey"],
            Configuration["CosmosDb:DbName"]);
    });
    
    ...
}

My DbContext looks very similar to any other.

public class BlogDbContext : DbContext
{
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>();
        var blog = modelBuilder.Entity<Post>().Metadata;
        // This needs to line up with the collection previously created
        blog.CosmosSql().CollectionName = nameof(Posts);
    }
}

Let's test ride

I've created a command (CQRS pattern) to add a post to the database, but I'm simply calling 2 lines inside it

await _dbContext.Posts.AddAsync(entity);
await _dbContext.SaveChangesAsync();

In my console app, I'm building up the entity before sending to the command and I'm printing the generated ID at the end. That's how it looks when it's running:
step10

Now we can check in the portal and see if the post was created.
step11

And voilà!!!

Hope it helps.

Cheers

Buy me a coffeeBuy me a coffee
Thiago Passos

Thiago Passos

I'm Thiago Passos, a Solution Architect working for SSW sharing what I've been working with and learning. Love technology, dancing and I get unfriendly when I'm hungry.

Read More