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.
Once the instance is created is time to create a new database
This is the database name we're going to use in our application, so save it.
And the collection is like a table in SQL, this is going to line up with a repository (DbSet)
Now give a name to your collection, but be very careful with the throughput.
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!!!
You're all set from here!
We just need some keys to configure our application
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
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:
Now we can check in the portal and see if the post was created.
And voilà!!!
Hope it helps.
Cheers