首页 > 解决方案 > 序列化 IList到 MongoDB 作为 BsonString 而不是 LUUID

问题描述

我在存储在 MongoDb 中的 guid 列表时遇到问题。我想将它们存储为字符串而不是 LUUID 条目。

目前,我正在使用 BsonRepresentation(BsonType.String) 属性表示法,但我想用初始化代码替换它,这样我就可以将所有内容保存在一个地方。

using System;
using System.Collections.Generic;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace Program.Dto
{
    public class Node
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public IList<Node> Groups { get; set; }
        [BsonRepresentation(BsonType.String)]
        public IList<Guid> Classes { get; set; }
        public static Node Create(string name)
        {
            return new Node
            {
                Id = Guid.NewGuid(),
                Name = name,
                Groups = new List<Node>(),
                Classes = new List<Guid>()
            };
        }
    }
}

这是我的初始化代码:

BsonClassMap.RegisterClassMap<Node>(cm =>
{
    cm.AutoMap();
    cm.SetIdMember(cm.GetMemberMap(c => c.Id));
    cm.GetMemberMap(c => c.Classes).SetSerializer(new GuidSerializer().WithRepresentation(BsonType.String));
});

但显然我遇到了一个错误,因为它是一个 List 而不是 Guid 本身。

System.ArgumentException: 'Value type of serializer is System.Guid  and does not match member type System.Collections.Generic.IList`1[[System.Guid, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].'

所以,我可能需要一个自定义序列化程序并附带类似的东西:

using System;
using System.Collections.Generic;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;

namespace Program.MongoDB.BsonSerializers
{
    public sealed class GuidListSerializer : BsonSerializerBase<IList<Guid>>
    {
        public override IList<Guid> Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            var guids = new List<Guid>();

            var bsonReader = context.Reader;
            bsonReader.ReadStartDocument();
            bsonReader.ReadString();
            bsonReader.ReadStartArray();

            while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
            {
                var guid = new Guid(bsonReader.ReadBinaryData().Bytes);
                guids.Add(guid);
                bsonReader.ReadEndArray();
            }

            bsonReader.ReadEndDocument();

            return guids.AsReadOnly();
        }

//Override the serialize method for storing guids as strings?

    }
}

但是我在 bsonReader.ReadEndArray() 上遇到错误,并且 MongoDb 中的条目存储为 LUUID 而不是字符串。

System.InvalidOperationException: 'ReadEndArray can only be called when State is EndOfArray, not when State is Value.'

我希望能够将 Guid 存储为字符串而不使用属性。

[BsonRepresentation(BsonType.String)]

标签: c#.netmongodbasp.net-core.net-core

解决方案


您应该检查阅读器的状态,并且仅在状态合适时才读取数组的末尾:

while (bsonReader.State != BsonReaderState.EndOfArray)
{
    var guid = new Guid(bsonReader.ReadBinaryData().Bytes);
    guids.Add(guid);
}

bsonReader.ReadEndArray();

推荐阅读