MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

BsonSerializationException beim Serialisieren eines Dictionary in BSON

Das Problem ist, dass der neue Treiber Wörterbücher standardmäßig als Dokument serialisiert.

Der MongoDB-C#-Treiber hat drei Möglichkeiten, ein Wörterbuch zu serialisieren:Document , ArrayOfArrays &ArrayOfDocuments (mehr dazu in den Dokumenten). Wenn es als Dokument serialisiert wird, sind die Wörterbuchschlüssel die Namen des BSON-Elements, das einige Einschränkungen hat (z. B. müssen sie, wie der Fehler andeutet, als Zeichenfolgen serialisiert werden).

In diesem Fall sind die Schlüssel des Wörterbuchs DateTime s, die nicht als Strings serialisiert werden, sondern als Date s also müssen wir eine andere DictionaryRepresentation wählen .

Um die Serialisierung dieser spezifischen Eigenschaft zu ändern, können wir die BsonDictionaryOptions verwenden Attribut mit einer anderen DictionaryRepresentation :

[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
public Dictionary<DateTime, int> Dictionary { get; private set; }

Wir müssen dies jedoch bei jedem problematischen Mitglied einzeln tun. Um diese DictionaryRepresentation anzuwenden An alle relevanten Mitglieder können wir eine neue Konvention implementieren:

class DictionaryRepresentationConvention : ConventionBase, IMemberMapConvention
{
    private readonly DictionaryRepresentation _dictionaryRepresentation;
    public DictionaryRepresentationConvention(DictionaryRepresentation dictionaryRepresentation)
    {
        _dictionaryRepresentation = dictionaryRepresentation;
    }
    public void Apply(BsonMemberMap memberMap)
    {
        memberMap.SetSerializer(ConfigureSerializer(memberMap.GetSerializer()));
    }
    private IBsonSerializer ConfigureSerializer(IBsonSerializer serializer)
    {
        var dictionaryRepresentationConfigurable = serializer as IDictionaryRepresentationConfigurable;
        if (dictionaryRepresentationConfigurable != null)
        {
            serializer = dictionaryRepresentationConfigurable.WithDictionaryRepresentation(_dictionaryRepresentation);
        }

        var childSerializerConfigurable = serializer as IChildSerializerConfigurable;
        return childSerializerConfigurable == null
            ? serializer
            : childSerializerConfigurable.WithChildSerializer(ConfigureSerializer(childSerializerConfigurable.ChildSerializer));
    }
} 

Welche wir wie folgt registrieren:

ConventionRegistry.Register(
    "DictionaryRepresentationConvention",
    new ConventionPack {new DictionaryRepresentationConvention(DictionaryRepresentation.ArrayOfArrays)},
    _ => true);