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:
- [Install and develop locally with Azure Cosmos DB Emulator | Microsoft Docs](Install and develop locally with Azure Cosmos DB Emulator | Microsoft Docs)
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
andsrc/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 removeMigrateDatabaseSchemaAsync
:
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.
Comments
John Tallon 109 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 68 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 65 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 89 weeks ago
Where is the article? You just added a link.
Enis Necipoğlu 88 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