1. 前言:
作为现代应用开发的"黄金搭档",C#与MongoDB的结合为处理非结构化数据提供了优雅的解决方案。MongoDB.Driver作为官方.NET驱动,其序列化机制就像"翻译官",在对象与Bson文档之间架起沟通桥梁。本文将手把手带您掌握这个"翻译官"的正确使用姿势。
2. 环境准备与基础配置
# 技术栈说明:
# - .NET 6.0+
# - MongoDB.Driver 2.19+
# - MongoDB 5.0+
// 初始化连接(建议单例模式)
var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("SampleDB");
var collection = database.GetCollection<User>("users");
3. 基础序列化示例:从对象到文档
public class User
{
[BsonId] // 声明主键字段
[BsonRepresentation(BsonType.ObjectId)] // 自动转换字符串为ObjectId
public string Id { get; set; }
[BsonElement("username")] // 自定义字段映射
public string Name { get; set; }
[BsonIgnoreIfNull] // 空值不序列化
public string Email { get; set; }
[BsonDateTimeOptions(Kind = DateTimeKind.Local)] // 时区处理
public DateTime CreatedAt { get; set; }
}
// 插入文档
await collection.InsertOneAsync(new User
{
Name = "张三",
Email = "zhangsan@example.com",
CreatedAt = DateTime.Now
});
// 查询文档
var filter = Builders<User>.Filter.Eq(u => u.Name, "张三");
var user = await collection.Find(filter).FirstOrDefaultAsync();
4. 自定义序列化:处理特殊场景
案例:枚举类型处理
public enum UserStatus { Active, Disabled }
BsonClassMap.RegisterClassMap<User>(cm =>
{
cm.MapProperty(u => u.Status)
.SetSerializer(new EnumSerializer<UserStatus>(BsonType.String));
});
// 序列化结果示例
{
"status": "Active" // 而非数值0
}
5. 复杂结构处理技巧
嵌套文档示例
public class Order
{
[BsonElement("items")]
public List<OrderItem> Items { get; set; }
}
public class OrderItem
{
[BsonElement("productName")]
public string Name { get; set; }
[BsonRepresentation(BsonType.Decimal128)] // 精确数值处理
public decimal Price { get; set; }
}
// 批量插入优化
var orders = GetLargeOrderList();
var options = new BulkWriteOptions { IsOrdered = false };
await collection.BulkWriteAsync(orders.Select(o =>
new InsertOneModel<Order>(o)), options);
6. 应用场景分析
适用场景:
- 快速迭代的数据模型(如用户行为日志)
- 需要灵活Schema的CMS系统
- 物联网设备时序数据存储
- 实时分析场景下的中间数据处理
7. 技术方案对比
特性 | MongoDB.Driver | Entity Framework | Dapper |
---|---|---|---|
序列化效率 | ★★★★☆ | ★★★☆☆ | ★★★★★ |
Schema灵活性 | ★★★★★ | ★★☆☆☆ | ★★★★☆ |
关联查询能力 | ★★☆☆☆ | ★★★★★ | ★★★★☆ |
开发便捷性 | ★★★★☆ | ★★★★★ | ★★★☆☆ |
8. 注意事项与性能优化
必须知道的坑:
- 连接池管理:单例模式复用MongoClient
var settings = new MongoClientSettings
{
MaxConnectionPoolSize = 100,
Server = new MongoServerAddress("localhost", 27017)
};
- 索引优化:为高频查询字段创建索引
var indexKeys = Builders<User>.IndexKeys.Ascending(u => u.Name);
await collection.Indexes.CreateOneAsync(new CreateIndexModel<User>(indexKeys));
- 数据模型设计三原则:
- 优先嵌入而非关联
- 控制文档大小在16MB以内
- 避免超过100层的嵌套
9. 总结:让数据流动更优雅
通过合理运用MongoDB.Driver的序列化机制,我们实现了:
- ✅ 自动化的类型转换
- ✅ 灵活的结构映射
- ✅ 高效的大数据处理
- ✅ 可控的存储优化
记住这些最佳实践:
- 优先使用属性注解配置
- 复杂类型显式注册ClassMap
- 批量操作使用BulkWrite
- 始终关注BSON文档结构
当您下次面对海量非结构化数据时,不妨试试这些"开箱即用"的技巧,让数据在C#与MongoDB之间优雅起舞!