Docs 菜单
Docs 主页
/ / /
C#/.NET
/ /

GUID

在此页面上

  • Overview
  • GuidRepresentationMode
  • V2
  • V3
  • 在 V3 中序列化 GUID
  • 在 V3 中序列化对象
  • 更多信息

在本指南中,您可以学习如何序列化全局唯一标识符 ( GUID),也称为通用唯一标识符 (UUID)。

提示

在 MongoDB 应用程序中, ObjectId 可以用作文档的唯一标识符。如果可能,考虑在 MongoDB 应用程序中使用 ObjectId 代替 GUID。

GUID 是一个 16 字节整数,可用作 MongoDB 文档的唯一 ID。最初,MongoDB 中的 GUID 表示为子类型 3 的 BsonBinaryData 值。子类型 3 在序列化期间没有标准化字节顺序,这导致 MongoDB 驱动程序之间的序列化不一致。为了标准化字节顺序并确保跨驱动程序序列化的一致性,我们创建 BsonBinaryData 子类型 4。

注意

对所有新 GUID 使用 BsonBinaryData 子类型 4。

在许多 MongoDB 集合中,所有 GUID 字段都使用相同的 BsonBinaryData 子类型。但是,某些较旧的集合可能包含一些使用子类型 3 的 GUID 字段和其他使用子类型 4 的其他字段。为了确保驱动程序正确序列化和反序列化所有 GUID,您应该将 BsonDefaults.GuidRepresentationMode 属性设置为以下 GuidRepresentationMode 值之一:

GuidRepresentationMode.V2 假定文档中的所有 GUID 使用相同的 BsonBinaryData 子类型。在此模式下,GUID 表示由读取器或写入器控制,而不是由序列化器控制。

V2 为默认的 GuidRepresentationMode

注意

当 .NET/C# 驱动程序版本 3 发布时,将从驱动程序中删除对 GuidRepresentationMode.V2 的支持,而默认值将变为 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 ignores writerSettings.GuidRepresentation

  • 调用不带 GuidRepresentation 参数的 BsonBinaryData.ToGuid() 方法仅适用于子类型 4 的 GUID。

注意

您无法在单个应用程序中同时使用 GuidRepresentationMode.V2GuidRepresentationMode.V3

GuidRepresentationMode.V3 在单个属性级别处理 GUID 序列化。此模式比 V2 更加灵活,但这也意味着您必须确保每个 GUID 字段都正确序列化和反序列化。

如果您使用 .NET/C# 驱动程序将 C# 类自动映射到文档模式,则可以使用 GUID 属性上的 BsonGuidRepresentation 属性来指定表示:

public class Widget
{
public int Id { get; set; }
[BsonGuidRepresentation(GuidRepresentation.Standard)]
public Guid G { get; set; }
}

注意

GuidRepresentation.Standard 相当于 BsonBinaryData 子类型 4。.NET/C# 驱动程序中的其他 GUID 表示(例如 CSharpLegacyJavaLegacyPythonLegacy)相当于子类型 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 属性。

您可以使用 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 文档:

后退

多态对象