How to use Cosmos DB in ABP?

There is a couple of ways to use Cosmos DB in C#. Cosmos DB has an SQL API and MongoDB API at the same time. Also there is a Entity Framework Provider of Cosmos DB which is based on SQL API but I recommend to use MongoDB Driver since Cosmos is a document based database. So, in this article, accessing to Cosmos DB will be with the MongoDB Driver.

Setting up Development Environment

There a Cosmos DB Emulator for development purposes. It's easy to setup for development.

You can follow those instructions to set up Cosmos DB for MongoDB Driver:

Notice: Do not forget to start emulator with /EnableMongoDbEndpoint parameter from CLI. The example is presented here.

Start Development

1- Creating ABP Application

In this example, we'll use MongoDB Driver to connect Cosmos DB as I said before, so let's create project with -d mongodb

 abp new Acme.BookStore -d mongodb -v 5.0.0-rc.1

2- Configuring the Project

Determine your connection string. If you're using default configuration of Cosmos DB Emulator, your connection string should be like below:

mongodb://localhost:C2y6yDjf5%2FR%2Bob0N8A7Cgv30VRDJIWEHLM%2B4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw%2FJw%3D%3D@localhost:10255/AcmeBookStore?ssl=true

Format is presented as Connection String URI Format. So you can make changes based on this format according to your requirements.

  • Replace connection string in src/Acme.BookStore.DbMigrator/appsettings.json and src/Acme.BookStore.Web/appsettings.json:
{
  "ConnectionStrings": {
-  "Default": "mongodb://localhost:27017/BookStore"
+  "Default": "mongodb://localhost:C2y6yDjf5%2FR%2Bob0N8A7Cgv30VRDJIWEHLM%2B4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw%2FJw%3D%3D@localhost:10255/AcmeBookStore?ssl=true"
  }
}

3- Configure & Run Migrations

Some more changes are required before running migrations. Creating a scheme isn't required anymore.

  • Go BookStoreDbMigrationService.cs file under Acme.BookStore.Domain/Data folder nd remove MigrateDatabaseSchemaAsync:
public async Task MigrateAsync()
{
    Logger.LogInformation("Started database migrations...");
-    await MigrateDatabaseSchemaAsync();
    await SeedDataAsync();
    Logger.LogInformation($"Successfully completed host database migrations.");
    var tenants = await _tenantRepository.GetListAsync(includeDetails: true);
-    var migratedDatabaseSchemas = new HashSet<string>();
    foreach (var tenant in tenants)
    {
        using (_currentTenant.Change(tenant.Id))
        {
            if (tenant.ConnectionStrings.Any())
            {
                var tenantConnectionStrings = tenant.ConnectionStrings
                    .Select(x => x.Value)
                    .ToList();
-                if (!migratedDatabaseSchemas.IsSupersetOf(tenantConnectionStrings))
-                {
-                    await MigrateDatabaseSchemaAsync(tenant);
-
-                    migratedDatabaseSchemas.AddIfNotContains(tenantConnectionStrings);
-                }
            }
            await SeedDataAsync(tenant);
        }
        Logger.LogInformation($"Successfully completed {tenant.Name} tenant database migrations.");
    }
    Logger.LogInformation("Successfully completed all database migrations.");
    Logger.LogInformation("You can safely end this process...");
}
  • Also you should remove entire method
-private async Task MigrateDatabaseSchemaAsync(Tenant tenant = null)
-{
-    Logger.LogInformation(
-    $"Migrating schema for {(tenant == null ? "host" : tenant.Name + " tenant")} database...");
-
-    foreach (var migrator in _dbSchemaMigrators)
-    {
-    await migrator.MigrateAsync();
-    }
-}
  • DbMigrator is ready to execute now. Run Acme.BookStore.DbMigrator project and complete data seeding.

After you see screen below, your application is completely ready.

4- Run the Project

Run the Acme.BookStore.Web project and see the result. All existing modules are working smooth with Cosmos DB.

CosmosDB
John Tallon 72 weeks ago

Hi there,

Is there any way that this version of this article could be updated, as the demo and code does not work when we run the db migrator.

Gets the following error

(Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: db43863e-1397-484a-a5c3-16788c009695; Reason: (Message: {"Errors":["The index path corresponding to the specified order-by item is excluded."]} ActivityId: db43863e-1397-484a-a5c3-16788c009695, Request URI: /apps/59f515ad-e858-49c8-b008-e910d2aaa706/services/18a994fe-bb98-4f08-a8a0-a493f8888f91/partitions/61f91739-5b6b-4ad1-ad43-03755cf0161a/replicas/133121451085768458s/, RequestStats: Microsoft.Azure.Cosmos.Tracing.TraceData.ClientSideRequestStatisticsTraceDatum, SDK: Windows/10.0.19041 cosmos-netstandard-sdk/3.18.0);););.'

This is on line 51 on the BookStoreDbMigrationService class.

var tenants = await _tenantRepository.GetListAsync(includeDetails: true);

Enis Necipoğlu 32 weeks ago

Hi, we've reproduced this issue in the latest ABP version, We'll try to figure it out and solve it

adrianadamiaksolutions@gmail.com 29 weeks ago

Hi Enis. Do you have any idea when it could be fixed? We have the plans to use the template and its the main blocker for us.

Ariful Islam 53 weeks ago

Where is the article? You just added a link.

Enis Necipoğlu 52 weeks ago

It seems there is an issue, you can access the article and example project with the following link:

https://github.com/abpframework/abp-samples/tree/dc803d90f7335fdc7427a26b487e5b9d95de30b0/CosmosDBSample#how-to-use-cosmos-db-in-abp