C#操作MongoDB如何通过BulkWriteAsync实现对象列表批量插入
可行性结论
完全可以通过BulkWriteAsync实现该批量插入需求。相比循环调用InsertOneAsync,批量写入会大幅减少客户端与MongoDB实例的网络往返次数,数据量较大时性能提升非常明显。
前置修正:实体类定义
你给出的类定义存在几处语法错误、字段匹配问题,先修正为可正常被MongoDB C#驱动序列化的版本:
using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; using System.Collections.Generic; public class A { [BsonId] public string _id { get; set; } // 若你预期存储的字段名是笔误的EMployeeInfo,保留BsonElement配置即可;如果是常规拼写Employee,修改对应参数值 [BsonElement("EMployeeInfo")] public List<EmployeeInfo> EmpInfo { get; set; } // 补全缺失的类型定义,根据示例值为字符串类型 public string AddedBy { get; set; } } // 补全缺失的class关键字 public class EmployeeInfo { [BsonElement("Name")] public string Name { get; set; } // 修正字段名大小写,和输入JSON的Contact字段匹配 [BsonElement("Contact")] public int Contact { get; set; } }
注:你给出的输入JSON存在语法错误(如
"Name":John"缺失前引号)、示例数据前后不一致(第二条文档Contact值和输入列表不匹配),实际使用时替换为正确合法的数据源即可。
具体实现代码
BulkWriteAsync的核心逻辑是将所有写入操作封装为WriteModel<T>类型的列表一次性提交,纯插入场景使用InsertOneModel<T>即可:
// 提前初始化完成的Mongo集合实例,替换为你实际的库、集合名 IMongoCollection<A> empCollection = database.GetCollection<A>("EmployeeCollection"); // 1. 完成数据源到目标文档结构的映射 const string fixedAddedBy = "XYZ"; // 这里替换为你从接口、文件等来源反序列化得到的员工输入列表 List<EmployeeInfo> inputEmployeeList = GetInputEmployeeData(); List<WriteModel<A>> bulkWriteOps = new List<WriteModel<A>>(); foreach (var singleEmp in inputEmployeeList) { // 每个员工生成一条独立文档,按你预期的结构赋值 A singleDoc = new A { // 若使用自定义业务id,替换为你的id生成逻辑即可 _id = ObjectId.GenerateNewId().ToString(), EmpInfo = new List<EmployeeInfo> { singleEmp }, AddedBy = fixedAddedBy }; // 将单条插入操作加入批量操作列表 bulkWriteOps.Add(new InsertOneModel<A>(singleDoc)); } // 2. 执行批量写入 BulkWriteResult writeResult = await empCollection.BulkWriteAsync( bulkWriteOps, new BulkWriteOptions { // 设为false时MongoDB无需严格按提交顺序执行,出错后继续执行剩余操作,性能更高 // 若需要严格保序、前序操作失败即终止,改为true即可 IsOrdered = false }); // 可通过返回结果校验写入成功条数,比如writeResult.InsertedCount
补充说明
- 如果你的批量操作只有插入,没有混合更新、删除、upsert需求,也可以直接使用更简便的
InsertManyAsync方法,底层实现逻辑和BulkWriteAsync的插入场景完全一致,性能没有差异;如果后续需要在同一次批量请求中混合多种写入操作,BulkWriteAsync灵活性更高。 - MongoDB单批写入的总数据大小上限为16MB,如果单次写入数据量极大,建议按每500~1000条拆分批次提交,避免触发大小限制报错。
- 如果不想定义强类型实体,也可以直接构造
BsonDocument作为泛型参数,用法和强类型版本完全一致。
内容的提问来源于stack exchange,提问作者Krypto456
相关产品推荐
相关产品推荐

