‹ 首页

abp-mongodb

@burakdmir · 收录于 昨天 · 上游提交 2 周前

ABP Framework v10.x (10.4/10.5) MongoDB: AbpMongoDbContext, collection mapping, index, transaction, replica set, repository. Use when working with MongoDB, document databases, or MongoDB repositories in ABP.

适合你,如果你正在ABP项目中使用MongoDB进行开发。

/ 通过 npx 安装 校验哈希
npx oh-my-skill add burakdmir/abp-skills/abp-mongodb
/ 通过 bash 安装
curl -fsSL https://oh-my-skill.com/install.sh | bash -s -- burakdmir/abp-skills/abp-mongodb
/ 已经装过?验证本机副本,不用重装
npx oh-my-skill verify burakdmir/abp-skills/abp-mongodb
安装目标可用 --agent / --scope 或 --to 明确指定;省略时只会在唯一已存在的 agent 目录上自动选择,零命中或多命中会停止并提示。content_hash 缺失或不一致均拒装。
13GitHub stars
~1.4K上下文体积 · 单文件
索引托管

怎么用

技能原文 SKILL.md作者撰写 · MIT · ce71259

ABP Framework — MongoDB

ABP Framework v10.x (10.4/10.5) MongoDB integration guide. MongoDbContext, collection mapping, repository, indexes, transactions.

Trigger
  • "ABP MongoDB"
  • "ABP MongoDbContext"
  • "ABP Mongo repository"
  • "ABP Mongo collection"
  • "ABP Mongo index"
  • "ABP Mongo transaction"
Installation
abp add-package Volo.Abp.MongoDB
[DependsOn(typeof(AbpMongoDbModule))]
public class MyModule : AbpModule { }
MongoDbContext
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
    }
}
Collection Mapping
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>();
Index Configuration
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 }
                )
            );
        });
    });
}
DbContext Registration
context.Services.AddMongoDbContext<MyDbContext>(options =>
{
    options.AddDefaultRepositories();
    // options.AddDefaultRepositories(includeAllEntities: true);
});
Using the Default Repository
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;
    }
}
Custom Repository
// 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
        );
    }
}
Default Repository Override
context.Services.AddMongoDbContext<MyMongoDbContext>(options =>
{
    options.AddDefaultRepositories();
    options.AddRepository<Book, BookRepository>();
});
MongoDB API Access
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.MongoDB package is required.
Transactions

MongoDB 4.0+ supports multi-document transactions. In the startup templates, transactions are disabled by default.

Enabling Transactions
// REMOVE the following code from the YourProjectMongoDbModule class:
// context.Services.AddAlwaysDisableUnitOfWorkTransaction();
// Configure<AbpUnitOfWorkDefaultOptions>(options =>
// {
//     options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled;
// });
Docker Replica Set (for Transactions)
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

Connection String Selection
[ConnectionStringName("MySecondConnString")]
public class MyDbContext : AbpMongoDbContext { }
Multi-Tenancy
[IgnoreMultiTenancy]  // Always use the host connection string
public class TenantManagementMongoDbContext : AbpMongoDbContext { }
Default Repository Base Class
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<>));
});
ReplaceDbContext Pattern
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>();
});
Bulk Operations Customization
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>(...) { }
}
EF Core vs MongoDB Comparison

| 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 |

Best Practices
  1. Use AbpMongoDbContext — Instead of directly using IMongoDatabase
  2. Define collection names via attribute[MongoCollection("name")]
  3. Define indexes in CreateModel — A migration-like approach
  4. Set up a replica set if you need transactions — A single node does not support transactions
  5. Define custom repositories in the MongoDB layer — Only the interface in the domain layer
  6. Use IAsyncQueryableExecuter — Keep the domain layer isolated from MongoDB
  7. Extra Properties are natively supported in MongoDB — Stored as a separate element instead of a JSON field

What's New in v10.5
  • MongoDB.Driver upgraded to 3.9.0 (v10.5+). If your solution pins MongoDB.Driver directly, align it with ABP's version and re-run integration tests that use the driver directly.
Related
  • [DDD](../abp-ddd/SKILL.md) — entity, aggregate, repository pattern
  • [EF Core](../abp-efcore/SKILL.md) — relational database alternative
  • [Dependency Rules](../abp-dependency-rules/SKILL.md) — repository interface/impl placement
  • [Multi-Tenancy](../abp-multitenancy/SKILL.md) — tenant data isolation
  • ABP Docs: https://abp.io/docs/latest/framework/data/mongodb
按 MIT 许可原样转载,未经改动 · 在 GitHub 查看 →

评论

登录即可评论;带「已验证安装」的,是发布者名下有本店的安装或持有记录。