From ABP Sensei
Guides ABP Framework v10.4 MongoDB integration: MongoDbContext setup, collection mapping, index configuration, transactions, and repository usage.
How this skill is triggered — by the user, by Claude, or both
Slash command
/abp-sensei:abp-mongodbThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
ABP Framework v10.4 MongoDB integration guide. MongoDbContext, collection mapping, repository, indexes, transactions.
ABP Framework v10.4 MongoDB integration guide. MongoDbContext, collection mapping, repository, indexes, transactions.
abp add-package Volo.Abp.MongoDB
[DependsOn(typeof(AbpMongoDbModule))]
public class MyModule : AbpModule { }
public class MyDbContext : AbpMongoDbContext
{
public IMongoCollection<Question> Questions => Collection<Question>();
public IMongoCollection<Category> Categories => Collection<Category>();
protected override void CreateModel(IMongoModelBuilder modelBuilder)
{
base.CreateModel(modelBuilder);
// Collection configuration
}
}
protected override void CreateModel(IMongoModelBuilder modelBuilder)
{
base.CreateModel(modelBuilder);
modelBuilder.Entity<Question>(b =>
{
b.CollectionName = "MyQuestions";
b.BsonMap.UnmapProperty(x => x.MyProperty); // Ignore property
});
}
Or via attribute:
[MongoCollection("MyQuestions")]
public IMongoCollection<Question> Questions => Collection<Question>();
protected override void CreateModel(IMongoModelBuilder modelBuilder)
{
base.CreateModel(modelBuilder);
modelBuilder.Entity<Question>(b =>
{
b.CreateCollectionOptions.Collation = new Collation(locale: "en_US", strength: CollationStrength.Secondary);
b.ConfigureIndexes(indexes =>
{
indexes.CreateOne(
new CreateIndexModel<BsonDocument>(
Builders<BsonDocument>.IndexKeys.Ascending("MyProperty"),
new CreateIndexOptions { Unique = true }
)
);
});
});
}
context.Services.AddMongoDbContext<MyDbContext>(options =>
{
options.AddDefaultRepositories();
// options.AddDefaultRepositories(includeAllEntities: true);
});
public class BookManager : DomainService
{
private readonly IRepository<Book, Guid> _bookRepository;
public BookManager(IRepository<Book, Guid> bookRepository) => _bookRepository = bookRepository;
public async Task<Book> CreateBookAsync(string name, BookType type)
{
var book = new Book(GuidGenerator.Create(), name, type);
await _bookRepository.InsertAsync(book);
return book;
}
}
// Interface (Domain layer)
public interface IBookRepository : IRepository<Book, Guid>
{
Task DeleteBooksByTypeAsync(BookType type, CancellationToken cancellationToken = default);
}
// Implementation (MongoDB layer)
public class BookRepository : MongoDbRepository<MyMongoDbContext, Book, Guid>, IBookRepository
{
public BookRepository(IMongoDbContextProvider<MyMongoDbContext> dbContextProvider)
: base(dbContextProvider) { }
public async Task DeleteBooksByTypeAsync(BookType type, CancellationToken cancellationToken = default)
{
var collection = await GetCollectionAsync(cancellationToken);
await collection.DeleteManyAsync(
Builders<Book>.Filter.Eq(b => b.Type, type),
cancellationToken
);
}
}
context.Services.AddMongoDbContext<MyMongoDbContext>(options =>
{
options.AddDefaultRepositories();
options.AddRepository<Book, BookRepository>();
});
public class BookService
{
private readonly IRepository<Book, Guid> _bookRepository;
public BookService(IRepository<Book, Guid> bookRepository) => _bookRepository = bookRepository;
public async Task FooAsync()
{
IMongoDatabase database = await _bookRepository.GetDatabaseAsync();
IMongoCollection<Book> books = await _bookRepository.GetCollectionAsync();
IAggregateFluent<Book> aggregate = await _bookRepository.GetAggregateAsync();
}
}
A reference to the
Volo.Abp.MongoDBpackage is required.
MongoDB 4.0+ supports multi-document transactions. In the startup templates, transactions are disabled by default.
// REMOVE the following code from the YourProjectMongoDbModule class:
// context.Services.AddAlwaysDisableUnitOfWorkTransaction();
// Configure<AbpUnitOfWorkDefaultOptions>(options =>
// {
// options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled;
// });
version: "3.8"
services:
mongo:
image: mongo:8.0
command: ["--replSet", "rs0", "--bind_ip_all", "--port", "27017"]
ports:
- 27017:27017
healthcheck:
test: echo "try { rs.status() } catch (err) { rs.initiate({_id:'rs0',members:[{_id:0,host:'127.0.0.1:27017'}]}) }" | mongosh --port 27017 --quiet
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
Connection string: mongodb://localhost:27017/YourProjectName?replicaSet=rs0
[ConnectionStringName("MySecondConnString")]
public class MyDbContext : AbpMongoDbContext { }
[IgnoreMultiTenancy] // Always use the host connection string
public class TenantManagementMongoDbContext : AbpMongoDbContext { }
public class MyRepositoryBase<TEntity> : MongoDbRepository<MyMongoDbContext, TEntity>
where TEntity : class, IEntity
{
public MyRepositoryBase(IMongoDbContextProvider<MyMongoDbContext> dbContextProvider)
: base(dbContextProvider) { }
}
context.Services.AddMongoDbContext<MyMongoDbContext>(options =>
{
options.SetDefaultRepositoryClasses(typeof(MyRepositoryBase<,>), typeof(MyRepositoryBase<>));
});
public interface IBookStoreMongoDbContext : IAbpMongoDbContext
{
IMongoCollection<Book> Books { get; }
}
[ReplaceDbContext(typeof(IBookStoreMongoDbContext))]
public class OtherMongoDbContext : AbpMongoDbContext, IBookStoreMongoDbContext { }
// or
context.Services.AddMongoDbContext<OtherMongoDbContext>(options =>
{
options.ReplaceDbContext<IBookStoreMongoDbContext>();
});
public class MyCustomMongoDbBulkOperationProvider : IMongoDbBulkOperationProvider, ITransientDependency
{
public async Task InsertManyAsync<TEntity>(
IMongoDbRepository<TEntity> repository,
IEnumerable<TEntity> entities,
IClientSessionHandle sessionHandle,
bool autoSave,
CancellationToken cancellationToken)
{
// Custom bulk insert logic
}
public async Task UpdateManyAsync<TEntity>(...) { }
public async Task DeleteManyAsync<TEntity>(...) { }
}
| Feature | EF Core | MongoDB |
|---|---|---|
| DbContext | AbpDbContext<T> | AbpMongoDbContext |
| Collection | DbSet<T> | IMongoCollection<T> |
| Mapping | Fluent API / Data Annotations | IMongoModelBuilder |
| Repository Base | EfCoreRepository | MongoDbRepository |
| Query | IQueryable (LINQ) | MongoDB Filter/Aggregate |
| Transaction | Enabled by default | Disabled by default |
| Change Tracking | Yes | No |
AbpMongoDbContext — Instead of directly using IMongoDatabase[MongoCollection("name")]CreateModel — A migration-like approachIAsyncQueryableExecuter — Keep the domain layer isolated from MongoDBnpx claudepluginhub burakdmir/abp-skills --plugin abp-senseiProvides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.