MongoClient直连即可CRUD,关键在过滤条件、原子更新和写入确认级别;连接字符串须含authSource,GetCollection泛型可为BsonDocument;Update需用Builders构建器保证类型安全,生产环境应设WriteConcern.WMajority。

直接用 MongoClient 连上就能做 CRUD,不需要额外封装或生成器。关键不是“能不能”,而是「过滤条件怎么写」「更新行为是否原子」「写入确认级别要不要调」——这些地方一错,数据就容易丢或查不到。
怎么连上 MongoDB 并拿到集合实例
连接字符串里必须包含数据库名(如 ?authSource=admin),否则 GetDatabase() 返回的实例可能无法正确鉴权;GetCollection<T>() 的泛型类型 T 不强制要求是实体类,用 BsonDocument 也完全可行,适合结构不固定或快速验证场景。
- 连接后不要立刻调用
collection.Find().ToList()测试,先用client.ListDatabaseNames().ToList()确认连通性和权限 - 如果服务端启用了访问控制,但连接字符串没带
authSource,会报Unauthorized: not authorized on admin to execute command { listDatabases: 1.0 } -
GetCollection<T>("users")不会自动创建集合,首次插入时才建,名称里不能含$或空格
UpdateOne 和 UpdateMany 的过滤和更新写法差异
UpdateOne() 和 UpdateMany() 都要传两个参数:一个是 FilterDefinition<T>,一个是 UpdateDefinition<T>。别直接拼 JSON 字符串,要用 Builders<T>.Filter.Eq()、Builders<T>.Update.Set() 这类构建器,否则字段名大小写、嵌套路径写错就查不到或更新失败。
- 过滤条件写成
new BsonDocument("name", "Alice")看似简单,但字段名不支持驼峰转下划线自动映射,推荐统一用Builders<User>.Filter.Eq(x => x.Name, "Alice") - 更新操作别用
Set("age", 30)这种字符串键,应改用Set(x => x.Age, 30),避免字段重命名后编译不报错但运行时报Element 'age' does not exist - 想实现“不存在就插入”,得用
ReplaceOne(..., new ReplaceOptions { IsUpsert = true }),UpdateOne默认不 upsert
WriteConcern 影响更新是否真正落盘
默认情况下 UpdateOne 只等主节点内存写入就返回,网络断开或主节点宕机可能导致更新丢失。生产环境建议显式设为 WriteConcern.WMajority,尤其在副本集部署中。
- 全局设置:构造
MongoClientSettings时赋值WriteConcern = WriteConcern.WMajority - 单次覆盖:调用
collection.WithWriteConcern(WriteConcern.WMajority).UpdateOne(...) - 设成
WriteConcern.Unacknowledged后,即使服务器根本没收到请求,方法也会立即返回成功 —— 这仅适合日志类非关键数据 - 事务内所有操作自动继承事务级
WriteConcern,无需单独设置
异步方法没 await 容易卡死或丢异常
InsertOneAsync、UpdateOneAsync 这些方法返回的是 Task,不是结果本身。在控制台程序里直接写 collection.UpdateOneAsync(...).Result 会死锁;在 ASP.NET Core 里不 await 则异常被吞掉,表面看没报错但数据没变。
- 同步写法仅限调试:用
collection.UpdateOneAsync(...).GetAwaiter().GetResult(),但上线必须换await - 批量更新别用循环加
await,改用UpdateManyAsync或InsertManyAsync,否则 IO 是串行的 - 如果用了
async void处理事件(比如按钮点击),异常无法被捕获,务必改成async Task
最容易被忽略的是过滤条件和更新定义的类型安全问题:用字符串写字段名,编译器不检查,运行时才暴露;还有 WriteConcern 的默认行为在开发机单节点和生产副本集下表现完全不同,不提前验证很容易上线后才发现更新“有时生效有时不”。


















