ABP MongoDB patterns - AbpMongoDbContext, IMongoCollection, MongoDbRepository, no migrations, embedded documents vs references, manual UpdateAsync required. Use when working in MongoDB projects or implementing MongoDB repositories in ABP.
[ConnectionStringName("Default")]
public class MyProjectMongoDbContext : AbpMongoDbContext
{
public IMongoCollection<Book> Books => Collection<Book>();
public IMongoCollection<Author> Authors => Collection<Author>();
protected override void CreateModel(IMongoModelBuilder modelBuilder)
{
base.CreateModel(modelBuilder);
modelBuilder.ConfigureMyProject();
}
}
public static class MyProjectMongoDbContextExtensions
{
public static void ConfigureMyProject(this IMongoModelBuilder builder)
{
Check.NotNull(builder, nameof(builder));
builder.Entity<Book>(b =>
{
b.CollectionName = MyProjectConsts.DbTablePrefix + "Books";
});
builder.Entity<Author>(b =>
{
b.CollectionName = MyProjectConsts.DbTablePrefix + "Authors";
});
}
}
public class BookRepository : MongoDbRepository<MyProjectMongoDbContext, Book, Guid>, IBookRepository
{
public BookRepository(IMongoDbContextProvider<MyProjectMongoDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async Task<Book> FindByNameAsync(
string name,
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await (await GetQueryableAsync())
.FirstOrDefaultAsync(
b => b.Name == name,
GetCancellationToken(cancellationToken));
}
public async Task<List<Book>> GetListByAuthorAsync(
Guid authorId,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await (await GetQueryableAsync())
.Where(b => b.AuthorId == authorId)
.ToListAsync(GetCancellationToken(cancellationToken));
}
}
[DependsOn(typeof(AbpMongoDbModule))]
public class MyProjectMongoDbModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddMongoDbContext<MyProjectMongoDbContext>(options =>
{
// Add default repositories for aggregate roots only (DDD best practice)
options.AddDefaultRepositories();
// ⚠️ Avoid includeAllEntities: true - breaks DDD data consistency
});
}
}
In appsettings.json:
{
"ConnectionStrings": {
"Default": "mongodb://localhost:27017/MyProjectDb"
}
}
MongoDB is schema-less; no migrations needed. Changes to entity structure are handled automatically.
Often ignored in MongoDB because documents typically embed related data:
public async Task<List<Book>> GetListAsync(
bool includeDetails = false, // Usually ignored
CancellationToken cancellationToken = default)
{
// MongoDB documents already include nested data
return await (await GetQueryableAsync())
.ToListAsync(GetCancellationToken(cancellationToken));
}
// Embedded (stored in same document)
public class Order : AggregateRoot<Guid>
{
public List<OrderLine> Lines { get; set; } // Embedded
}
// Reference (separate collection, store ID only)
public class Order : AggregateRoot<Guid>
{
public Guid CustomerId { get; set; } // Reference by ID
}
MongoDB doesn't track entity changes automatically:
public async Task UpdateBookAsync(Guid id, string newName)
{
var book = await _bookRepository.GetAsync(id);
book.SetName(newName);
// Must explicitly update
await _bookRepository.UpdateAsync(book);
}
public async Task CustomOperationAsync()
{
var collection = await GetCollectionAsync();
// Use MongoDB driver directly
var filter = Builders<Book>.Filter.Eq(b => b.AuthorId, authorId);
var update = Builders<Book>.Update.Set(b => b.IsPublished, true);
await collection.UpdateManyAsync(filter, update);
}
Configure indexes in repository or via MongoDB driver:
public class BookRepository : MongoDbRepository<MyProjectMongoDbContext, Book, Guid>, IBookRepository
{
public override async Task<IQueryable<Book>> GetQueryableAsync()
{
var collection = await GetCollectionAsync();
// Ensure index exists
var indexKeys = Builders<Book>.IndexKeys.Ascending(b => b.Name);
await collection.Indexes.CreateOneAsync(new CreateIndexModel<Book>(indexKeys));
return await base.GetQueryableAsync();
}
}
GetCancellationToken(cancellationToken) for proper cancellation