Overview
在本指南中,您可以了解如何使用 MongoDB .NET/C# 驱动程序执行序列化。序列化是将 C# 对象映射到 BSON 文档以存储在 MongoDB 中的过程。
序列化器
序列化器是处理 C# 对象与 BSON 文档之间转换的类。 序列化器实施 IBsonSerializer
接口。 .NET/C# 驱动程序有许多内置序列化器,用于处理基元类型、集合类型和自定义类。
ObjectSerializer
ObjectSerializer
类只允许对被视为安全的类型进行序列化和反序列化。构造 ObjectSerializer
时,可以传入类型为 Func<Type, bool>
的委托。此委托接受一个对象类型并返回一个布尔值,指示该类型是否可以安全地序列化。
在大多数情况下,请传入 ObjectSerializer.DefaultAllowedTypes()
委托。对于我们认为安全的几种知名框架类型,此方法会返回 true。要序列化自定义类型,请为要包含的类型创建一个值为 true
的布尔表达式。然后,将此表达式添加到传递给 ObjectSerializer
构造函数的委托的末尾。
在以下示例中,ObjectSerializer
会序列化和反序列化ObjectSerializer.DefaultAllowedTypes()
允许的或其全名以 "MyNamespace"
开头的任何类型:
var objectSerializer = new ObjectSerializer(type => ObjectSerializer.DefaultAllowedTypes(type) || type.FullName.StartsWith("MyNamespace")); BsonSerializer.RegisterSerializer(objectSerializer);
要允许序列化匿名类型,请将布尔表达式 type.FullName.StartsWith("<>f__AnonymousType"))
添加到委托中,如如下示例所示:
var objectSerializer = new ObjectSerializer(type => ObjectSerializer.DefaultAllowedTypes(type) || type.FullName.StartsWith("<>f__AnonymousType")); BsonSerializer.RegisterSerializer(objectSerializer);
在执行任何其他操作之前,请在程序启动时创建并注册 ObjectSerializer
。
序列化器注册表
序列化器注册表包含您的应用程序可用的所有已注册的序列化器。许多内置序列化器在应用程序启动时会自动注册到序列化器注册表中。但是,在使用自定义序列化器之前,您必须将其添加到序列化器注册表中,如下例所示:
BsonSerializer.RegisterSerializer(new CustomTypeSerializer());
如要访问序列化器注册表,请使用 BsonSerializer
类的 SerializerRegistry
属性,如下所示:
var intSerializer = BsonSerializer.SerializerRegistry.GetSerializer<int>();
重要
序列化器注册表是一个全局注册表。这表示您不能在单个应用程序中使用多个注册表。
自定义序列化器
要创建自己的自定义序列化器,实现IBsonSerializer
基类,设立ValueType
成员,并重写 Deserialize()
和 Serialize()
方法。
以下代码示例显示了自定义 BsonRegularExpression
序列化器:
class CustomRegularExpressionSerializer : IBsonSerializer { public Type ValueType => typeof(Regex); public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) { var type = context.Reader.CurrentBsonType; switch (type) { case BsonType.RegularExpression: return context.Reader.ReadRegularExpression().AsRegex; case BsonType.String: var pattern = context.Reader.ReadString() return new Regex(pattern); default: throw new NotSupportedException($"Cannot convert a {type} to a RegularExpression."); } } public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value) { var regex = (Regex) value; context.Writer.WriteRegularExpression(regex); } }
选择加入界面
.NET/C# 驱动程序具有多个可选接口,您的自定义序列化器类可以实现这些接口,具体取决于序列化器处理的数据类型。
IBsonIdProvider
IBsonIdProvider 接口提供 和GetDocumentId()
SetDocumentId()
方法,如果要序列化的对象使用_id
以外的ObjectId
类型,则该接口非常有用。
IBsonDocumentSerializer
实现 IBsonDocumentSerializer 接口使驾驶员能够访问权限正在序列化的对象的成员信息。这允许驾驶员在使用自定义序列化器时正确构造类型安全的查询。
IBsonArraySerializer
实现 IBsonArraySerializer 接口使驾驶员能够访问权限大量中各个项目的序列化信息。
提高数组序列化性能
您可以将基元数组表示为 Memory<T> 和 ReadOnlyMemory<T> 结构体,而不是使用标准C#数组或BsonArray
对象等类型,从而提高应用程序的性能。驾驶员为Memory<T>
和ReadOnlyMemory<T>
实现快速序列化和反序列化路径,从而提高速度并减少内存使用量。
注意
Memory<T>
或 ReadOnlyMemory<T>
不支持截断和溢出检查,但这些检查是针对标准数组实施的。
您可以通过将以下基元类型存储在 Memory<T>
或 ReadOnlyMemory<T>
结构中来实现这些性能改进:
bool
sbyte
byte
char
short
ushort
int
uint
long
ulong
float
double
decimal
以下示例定义了一个 Line
POCO,其中包含由 Memory
和 ReadOnlyMemory
结构体建模的大量字段:
public class Line { public ObjectId Id { get; set; } public Memory<int> X { get; set; } public ReadOnlyMemory<float> Y { get; set; } }
以下文档展示了示例Line
对象在MongoDB中的表示方式:
{ "_id": ..., "X": [ 1, 2, 3, 4, 5 ], "Y": [ 1, 1.409999966621399, 1.7300000190734863, 2, 2.240000009536743 ] }
更多信息
要了解有关使用 .NET/C# 驱动程序序列化 C# 对象的更多信息,请参阅以下页面:
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: