当前位置: 首页 > news >正文

企业网站建设公司排名国外b站浏览器

企业网站建设公司排名,国外b站浏览器,科技网站建设+长沙,固原网站制作🚀 ABP VNext MongoDB 数据存储:多模型支持与 NoSQL 扩展(生产级实践) 目录 🚀 ABP VNext MongoDB 数据存储:多模型支持与 NoSQL 扩展(生产级实践)🎯 引言&#x1f9f0…

🚀 ABP VNext + MongoDB 数据存储:多模型支持与 NoSQL 扩展(生产级实践)


目录

  • 🚀 ABP VNext + MongoDB 数据存储:多模型支持与 NoSQL 扩展(生产级实践)
    • 🎯 引言
    • 🧰 环境与依赖
      • ⚙️ appsettings.json
    • 🏗️ 架构概述
    • 🤖 集成与配置
      • 📑 模块注册
      • 📘 DbContext 定义
    • 📦 自定义仓储实现
    • 🔐 事务处理与一致性
      • 🔄 UnitOfWork 流程
    • 🗺️ 分片与模型设计
      • 🔑 Shard Key 评估
      • 🏗️ 多模型建模
    • 🚀 性能优化指南
      • 📈 索引创建
      • ⚡ 批量写入
    • 📊 监控与可观测性
      • 🐢 慢查询检测(CommandSucceededEvent)
      • 🌐 Application Insights
    • 🛠️ Controller 全 CRUD 示例
    • 🧪 单元测试示例(xUnit + Mongo2Go + DI)
    • 📚 附录


🎯 引言

在高并发、快速迭代的业务环境中,传统 RDBMS 因结构僵硬、事务开销大而难以应对。MongoDB 以其灵活文档模型、高吞吐与分布式能力,成为 ABP 应用的理想补充。本文将示范如何在 ABP VNext 中生产级地集成 MongoDB——从配置、DI、仓储,到事务、多模型设计与监控全覆盖。

💬 业务痛点

  • 频繁迭代导致表结构变更成本高
  • 大规模写入时事务与锁竞争瓶颈明显
  • 多租户隔离需高扩展性

🧰 环境与依赖

  • 🖥️ .NET 8
  • 📦 ABP v6+
  • 🌐 MongoDB Server 6.x(Replica Set / Sharded Cluster)
  • 📦 NuGet 包
    • MongoDB.Driver
    • Volo.Abp.MongoDB

⚙️ appsettings.json

{"ConnectionStrings": {"MongoDb": "mongodb://localhost:27017/?maxPoolSize=200&minPoolSize=50"},"MongoDb": {"DatabaseName": "MyProjectDb"}
}

🏗️ 架构概述

📩 HTTP 请求
🔧 Application Service
📦 Domain Service
📚 MongoRepository
🗄️ MyMongoDbContext
🌐 MongoDB Server

🤖 集成与配置

📑 模块注册

public override void PreConfigureServices(ServiceConfigurationContext context)
{Configure<AbpMongoDbContextOptions>(options =>{options.ConnectionStringName = "MongoDb";});
}public override void ConfigureServices(ServiceConfigurationContext context)
{context.Services.AddMongoDbContext<MyMongoDbContext>(builder =>{// includeAllEntities: false 仅为聚合根生成仓储builder.AddDefaultRepositories(includeAllEntities: false);});
}

💡 可根据项目需要,将 includeAllEntities 设置为 truefalse

📘 DbContext 定义

[ConnectionStringName("MongoDb")]
[MultiTenant]
public class MyMongoDbContext : AbpMongoDbContext
{public IMongoCollection<Order> Orders => Database.GetCollection<Order>("Orders");public IMongoCollection<Address> Addresses => Database.GetCollection<Address>("Addresses");public MyMongoDbContext(IAbpMongoDbContextOptions<MyMongoDbContext> options): base(options) { }
}
  • 建议:在模块 PreConfigureServices 注入 ICurrentTenant 控制数据库路由。

📦 自定义仓储实现

public interface IMongoRepository<TEntity, TKey> : IRepository<TEntity, TKey>where TEntity : class, IEntity<TKey>
{Task BulkInsertAsync(IEnumerable<TEntity> entities, bool isOrdered = false);Task<IEnumerable<TResult>> AggregateLookupAsync<TForeign, TResult>(Expression<Func<TEntity, object>> localField,Expression<Func<TForeign, object>> foreignField,PipelineDefinition<TEntity, TResult> pipeline);
}public class MongoRepository<TEntity, TKey>: MongoDbRepository<MyMongoDbContext, TEntity, TKey>, IMongoRepository<TEntity, TKey>where TEntity : class, IEntity<TKey>
{private readonly IMongoCollection<TEntity> _collection;public MongoRepository(IDbContextProvider<MyMongoDbContext> dbContextProvider): base(dbContextProvider){_collection = dbContextProvider.GetDbContext().Database.GetCollection<TEntity>(typeof(TEntity).Name);}public async Task BulkInsertAsync(IEnumerable<TEntity> entities, bool isOrdered = false){var models = entities.Select(e => new InsertOneModel<TEntity>(e));await _collection.BulkWriteAsync(models, new BulkWriteOptions { IsOrdered = isOrdered });}public async Task<IEnumerable<TResult>> AggregateLookupAsync<TForeign, TResult>(Expression<Func<TEntity, object>> localField,Expression<Func<TForeign, object>> foreignField,PipelineDefinition<TEntity, TResult> pipeline){return await _collection.Aggregate(pipeline).ToListAsync();}
}

🔐 事务处理与一致性

🔄 UnitOfWork 流程

Controller AppService UnitOfWork Repository CreateAsync(input) BeginTransaction() InsertAsync(order) Acknowledged Commit() Completed Return OrderDto Controller AppService UnitOfWork Repository
public class OrderAppService : ApplicationService, IOrderAppService
{private readonly IMongoRepository<Order, Guid> _orderRepository;public OrderAppService(IMongoRepository<Order, Guid> orderRepository)=> _orderRepository = orderRepository;[UnitOfWork]public async Task<OrderDto> CreateAsync(CreateOrderDto input){var order = ObjectMapper.Map<Order>(input);await _orderRepository.InsertAsync(order);return ObjectMapper.Map<OrderDto>(order);}
}

🗺️ 分片与模型设计

🔑 Shard Key 评估

sh.shardCollection("MyProjectDb.Orders", { CustomerId: 1, CreatedAt: 1 });

⚠️ 复合键示例,可有效避免单一热点。

🏗️ 多模型建模

引用模型
AddressId
Order
Address 集合
嵌入式
Address 嵌入
Order
// 示例 $lookup 聚合
var results = await _context.Orders.Aggregate().Lookup<Address, LookupResult>(_context.Addresses,o => o.AddressId,a => a.Id,result => result.Addresses).ToListAsync();

🚀 性能优化指南

📈 索引创建

var orderCollection = context.Database.GetCollection<Order>("Orders");
await orderCollection.Indexes.CreateManyAsync(new[]
{new CreateIndexModel<Order>(Builders<Order>.IndexKeys.Ascending(o => o.CustomerId)),new CreateIndexModel<Order>(Builders<Order>.IndexKeys.Descending(o => o.CreatedAt))
});

⚡ 批量写入

await repository.BulkInsertAsync(largeOrderList, isOrdered: false);

🛠️ 捕获 BulkWriteException 并重试或补偿处理。


📊 监控与可观测性

🐢 慢查询检测(CommandSucceededEvent)

Configure<AbpMongoOptions>(options =>
{options.ClusterConfigurator = cb =>{cb.Subscribe<CommandSucceededEvent>(e =>{if (e.CommandName == "find" && e.Duration > TimeSpan.FromMilliseconds(100)){Logger.LogWarning("🐢 Slow MongoDB query: {Command}", e.Command);}});};
});

🌐 Application Insights

services.AddApplicationInsightsTelemetry();
var telemetryClient = serviceProvider.GetRequiredService<TelemetryClient>();
// 示例上报连接池使用率
var poolUsage = /* 读取连接池状态 */;
telemetryClient.TrackMetric("mongo.connectionPoolUsage", poolUsage);

🛠️ Controller 全 CRUD 示例

[ApiController]
[Route("api/orders")]
public class OrdersController : AbpController
{private readonly IOrderAppService _service;public OrdersController(IOrderAppService service) => _service = service;[HttpPost][ProducesResponseType(typeof(OrderDto), 201)]public async Task<OrderDto> Create(CreateOrderDto input){return await _service.CreateAsync(input);}[HttpGet("{id}")][ProducesResponseType(typeof(OrderDto), 200)][ProducesResponseType(404)]public Task<OrderDto> Get(Guid id) => _service.GetAsync(id);[HttpPut("{id}")][ProducesResponseType(typeof(OrderDto), 200)]public Task<OrderDto> Update(Guid id, UpdateOrderDto input){input.Id = id;return _service.UpdateAsync(input);}[HttpDelete("{id}")][ProducesResponseType(204)]public Task Delete(Guid id) => _service.DeleteAsync(id);
}

🧪 单元测试示例(xUnit + Mongo2Go + DI)

public class OrderRepositoryTests : IClassFixture<ServiceFixture>
{private readonly IMongoRepository<Order, Guid> _repository;public OrderRepositoryTests(ServiceFixture fixture){_repository = fixture.ServiceProvider.GetRequiredService<IMongoRepository<Order, Guid>>();}[Fact]public async Task BulkInsert_Should_Insert_All_Orders(){var orders = Enumerable.Range(1, 10).Select(i => new Order { Id = Guid.NewGuid(), CustomerId = $"C{i}" }).ToList();await _repository.BulkInsertAsync(orders);var count = await _repository.GetCountAsync();Assert.Equal(10, count);}[Fact]public async Task Update_Should_Modify_Order(){var order = await _repository.InsertAsync(new Order { Id = Guid.NewGuid(), CustomerId = "C0" });order.CustomerId = "C0-Updated";await _repository.UpdateAsync(order);var fetched = await _repository.GetAsync(order.Id);Assert.Equal("C0-Updated", fetched.CustomerId);}[Fact]public async Task Delete_Should_Remove_Order(){var order = await _repository.InsertAsync(new Order { Id = Guid.NewGuid(), CustomerId = "C1" });await _repository.DeleteAsync(order.Id);await Assert.ThrowsAsync<EntityNotFoundException>(() => _repository.GetAsync(order.Id));}
}public class ServiceFixture : IDisposable
{public ServiceProvider ServiceProvider { get; }public ServiceFixture(){var runner = MongoDbRunner.Start();var services = new ServiceCollection();services.Configure<AbpMongoDbContextOptions<MyMongoDbContext>>(options =>{options.ConnectionStringName = "MongoDb";});services.AddMongoDbContext<MyMongoDbContext>(builder =>{builder.AddDefaultRepositories(includeAllEntities: false);});services.AddTransient(typeof(IMongoRepository<,>), typeof(MongoRepository<,>));services.AddSingleton(runner);ServiceProvider = services.BuildServiceProvider();}public void Dispose(){var runner = ServiceProvider.GetRequiredService<MongoDbRunner>();runner.Dispose();}
}

📚 附录

  • ABP 官方文档:https://docs.abp.io
  • MongoDB 索引指南:https://www.mongodb.com/docs/manual/indexes/
  • Mongo2Go:https://github.com/Mongo2Go/Mongo2Go

文章转载自:
http://toilless.c7510.cn
http://molluscum.c7510.cn
http://reckoner.c7510.cn
http://irreverent.c7510.cn
http://polaroid.c7510.cn
http://prosciutto.c7510.cn
http://spironolactone.c7510.cn
http://misinform.c7510.cn
http://ballista.c7510.cn
http://bbs.c7510.cn
http://inspiringly.c7510.cn
http://siderostat.c7510.cn
http://centroid.c7510.cn
http://mullet.c7510.cn
http://correction.c7510.cn
http://gannet.c7510.cn
http://annemarie.c7510.cn
http://pond.c7510.cn
http://sublieutenant.c7510.cn
http://detumescence.c7510.cn
http://aport.c7510.cn
http://revaccination.c7510.cn
http://prompt.c7510.cn
http://polymorph.c7510.cn
http://syllepsis.c7510.cn
http://bandoline.c7510.cn
http://marian.c7510.cn
http://satang.c7510.cn
http://azury.c7510.cn
http://lentiginous.c7510.cn
http://huzoor.c7510.cn
http://glucosan.c7510.cn
http://feedway.c7510.cn
http://demogorgon.c7510.cn
http://pneumatically.c7510.cn
http://underfur.c7510.cn
http://gelation.c7510.cn
http://monoestrous.c7510.cn
http://hypophosphatasia.c7510.cn
http://cyrenaicism.c7510.cn
http://hymenium.c7510.cn
http://protamine.c7510.cn
http://cookbook.c7510.cn
http://unstring.c7510.cn
http://chatterbox.c7510.cn
http://irenics.c7510.cn
http://lancastrian.c7510.cn
http://aepyornis.c7510.cn
http://felv.c7510.cn
http://cranic.c7510.cn
http://misbound.c7510.cn
http://reset.c7510.cn
http://mesochroic.c7510.cn
http://manzello.c7510.cn
http://malayan.c7510.cn
http://epileptogenic.c7510.cn
http://imperceivable.c7510.cn
http://coydog.c7510.cn
http://copperhead.c7510.cn
http://decapacitate.c7510.cn
http://ectal.c7510.cn
http://rollpast.c7510.cn
http://misorient.c7510.cn
http://motility.c7510.cn
http://oxalis.c7510.cn
http://inanga.c7510.cn
http://baudelairean.c7510.cn
http://semiautomated.c7510.cn
http://hiron.c7510.cn
http://cither.c7510.cn
http://tyrannous.c7510.cn
http://heterogenous.c7510.cn
http://pinery.c7510.cn
http://rubious.c7510.cn
http://homespun.c7510.cn
http://victoria.c7510.cn
http://brunet.c7510.cn
http://csf.c7510.cn
http://adventive.c7510.cn
http://ejaculation.c7510.cn
http://idiolectal.c7510.cn
http://documentary.c7510.cn
http://mount.c7510.cn
http://provisionality.c7510.cn
http://gerontocracy.c7510.cn
http://sundae.c7510.cn
http://laevo.c7510.cn
http://unlib.c7510.cn
http://thein.c7510.cn
http://antiwar.c7510.cn
http://viticulturist.c7510.cn
http://florin.c7510.cn
http://insulant.c7510.cn
http://wbo.c7510.cn
http://ludditish.c7510.cn
http://pally.c7510.cn
http://natation.c7510.cn
http://rhyming.c7510.cn
http://severally.c7510.cn
http://minder.c7510.cn
http://www.zhongyajixie.com/news/80249.html

相关文章:

  • 湖南做网站 真好磐石网络营销策划的六个步骤
  • 湖南省人民政府电话号码免费seo工具汇总
  • 网站做视频播放占用cpu吗广东培训seo
  • 网站设计模版免费建站怎么把平台推广出去
  • 怎么做微信网站推广如何做网站搜索引擎优化
  • 东营seo网站建设费用校园推广
  • 深圳市大型公司海口网站关键词优化
  • 做游戏代练去那个网站磁力链最佳的搜索引擎
  • 高密哪里做网站游戏推广员如何推广引流
  • 营销软件网站建设免费网站流量统计
  • wordpress 全图片seo排名点击工具
  • 游戏网站建设策划方案模板百中搜优化
  • 网站的分辨率是多少seo怎样
  • 河北省石家庄疫情最新情况寰宇seo
  • 行业网站设计开发费用信息流优化师需要具备哪些能力
  • 怎么做各类网站直通车官网
  • 做网站得做多少网页百度权重工具
  • wordpress安装流程图郑州seo网络推广
  • 用了wordpress的网站长沙的seo网络公司
  • 网站更换主机长沙seo推广优化
  • 专业做网盘资源收录分享的网站北京网站优化推广方案
  • 南宁建筑规划设计集团有限公司搜索引擎优化概述
  • 免费网站建设网站开发公司百度电脑端网页版入口
  • 站长工具排名查询友情链接检测平台
  • 网站的兼容性竞价培训
  • 复古网站设计百度广告投诉电话客服24小时
  • vs做网站的书籍做网站公司哪家正规
  • 导航网站帝国cms模版百度seo指数查询
  • 做视频类网站需要哪些许可推广优化
  • 一个做flash的网站电商运营seo