GUID
Overview
在本指南中,您可以学习如何序列化全局唯一标识符 (GUID),也称为通用唯一标识符 (UUID)。
提示
在 MongoDB 应用程序中, ObjectId
可以用作文档的唯一标识符。如果可能,考虑在 MongoDB 应用程序中使用 ObjectId
代替 GUID。
GUID 是一个 16 字节整数,可用作 MongoDB 文档的唯一 ID。最初,MongoDB 中的 GUID 表示为子类型 3 的 BsonBinaryData
值。子类型 3 在序列化期间没有标准化字节顺序,这导致 MongoDB 驱动程序之间的序列化不一致。为了标准化字节顺序并确保跨驱动程序序列化的一致性,我们创建 BsonBinaryData
子类型 4。
注意
对所有新 GUID 使用 BsonBinaryData
子类型 4。
GuidRepresentationMode
在许多 MongoDB 集合中,所有 GUID 字段都使用相同的 BsonBinaryData
子类型。但是,某些较旧的集合可能包含一些使用子类型 3 的 GUID 字段和其他使用子类型 4 的其他字段。为了确保驱动程序正确序列化和反序列化所有 GUID,您应该将 BsonDefaults.GuidRepresentationMode
属性设置为以下 GuidRepresentationMode
值之一:
V2
GuidRepresentationMode.V2
假定文档中的所有 GUID 使用相同的 BsonBinaryData
子类型。在此模式下,GUID 表示由读取器或写入器控制,而不是由序列化器控制。
V2
为默认的 GuidRepresentationMode
。
注意
当 .NET/C# 驱动程序版本 3 发布时,将从驱动程序中删除对 GuidRepresentationMode.V2
的支持,而默认值将变为 V3
。
V3
GuidRepresentationMode.V3
允许同一文档中的字段使用不同的 GUID 格式。在此模式下,通过为每个属性配置序列化器在属性级别控制 GUID 表示。
要使用 GuidRepresentationMode.V3
,运行以下代码。应用程序在创建 MongoClient
对象之前在应用程序的快速启动阶段运行此代码。
BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3;
在 V3
模式下运行会通过以下方式更改驱动程序的行为:
BsonBinaryReader.ReadBinaryData()
方法忽略readerSettings.GuidRepresentation
BsonBinaryWriter.WriteBinaryData()
方法忽略writerSettings.GuidRepresentation
JsonReader.ReadBinaryData()
方法忽略readerSettings.GuidRepresentation
JsonWriter
ignoreswriterSettings.GuidRepresentation
调用不带
GuidRepresentation
参数的BsonBinaryData.ToGuid()
方法仅适用于子类型 4 的 GUID。
注意
您无法在单个应用程序中同时使用 GuidRepresentationMode.V2
和 GuidRepresentationMode.V3
。
在 V3 中序列化 GUID
GuidRepresentationMode.V3
在单个属性级别处理 GUID 序列化。此模式比 V2
更加灵活,但这也意味着您必须确保每个 GUID 字段都正确序列化和反序列化。
如果您使用 .NET/C# 驱动程序将 C# 类自动映射到文档模式,则可以使用 GUID 属性上的 BsonGuidRepresentation
属性来指定表示:
public class Widget { public int Id { get; set; } [ ] public Guid G { get; set; } }
注意
GuidRepresentation.Standard
相当于 BsonBinaryData
子类型 4。.NET/C# 驱动程序中的其他 GUID 表示(例如 CSharpLegacy
、JavaLegacy
和 PythonLegacy
)相当于子类型 3,但使用不同的字节顺序。
如果您正在编写自己的序列化代码,则可以使用 GuidSerializer
类对 BSON 字段中的各个 GUID 值进行序列化和反序列化。为了确保驱动程序正确处理 GUID,在构建 GuidSerializer
时使用 GuidRepresentation
参数。
以下代码示例创建 GuidSerializer
实例来序列化子类型 4 的 GUID 表示:
var guidSerializer = new GuidSerializer(GuidRepresentation.Standard);
如果您的大多数 GUID 使用相同的表示,您可以全局注册 GuidSerializer
。要创建并注册 GuidSerializer
,在应用程序的早期运行以下代码,例如在快速启动阶段:
BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
提示
当使用两个子类型时,您可以将全局序列化器与 BsonGuidRepresentation
属性结合起来。例如,您可以为最常用的 GUID 子类型注册全局序列化器,然后使用 BsonGuidRepresentation
属性表示另一个子类型的任何 GUID 属性。
在 V3 中序列化对象
您可以使用 ObjectSerializer
将层级对象序列化为子文档。为了确保在使用 V3
时正确序列化和反序列化这些对象中的 GUID,您应该在构建 ObjectSerializer
时选择正确的 GUID 表示。
以下代码示例展示如何为子类型 4 的 GUID 表示创建 ObjectSerializer
:
var objectDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); var objectSerializer = new ObjectSerializer(objectDiscriminatorConvention, GuidRepresentation.Standard);
如果您的应用程序依赖 ObjectSerializer
序列化任何 GUID,您还必须在应用程序的早期注册序列化器,例如在快速启动阶段。每当需要对象序列化器且未另行指定时,您注册的序列化器将在全局范围内使用。
要注册您的 ObjectSerializer
,将其传递给 BsonSerializer.RegisterSerializer()
方法:
var objectDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object)); var objectSerializer = new ObjectSerializer(objectDiscriminatorConvention, GuidRepresentation.Standard); BsonSerializer.RegisterSerializer(objectSerializer);
更多信息
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: