sql >> Databasteknik >  >> NoSQL >> MongoDB

BsonSerializationException vid serialisering av en Dictionary till BSON

Problemet är att den nya drivrutinen serialiserar ordböcker som ett dokument som standard.

MongoDB C#-drivrutinen har tre sätt att serialisera en ordbok:Document , ArrayOfArrays &ArrayOfDocuments (mer om det i dokumenten). När det serialiseras som ett dokument är ordboksnycklarna namnen på BSON-elementet som har vissa begränsningar (till exempel, som felet antyder, måste de serialiseras som strängar).

I det här fallet är ordbokens nycklar DateTime s som inte är serialiserade som strängar, utan som Date s så vi måste välja en annan DictionaryRepresentation .

För att ändra serialiseringen av denna specifika egenskap kan vi använda BsonDictionaryOptions attribut med en annan DictionaryRepresentation :

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

Men vi måste göra det på varje problematisk medlem individuellt. För att tillämpa denna DictionaryRepresentation till alla relevanta medlemmar kan vi implementera en ny konvention:

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));
    }
} 

Som vi registrerar enligt följande:

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


  1. 6 bästa MapReduce Job Optimization Techniques

  2. Mongo-aggregation med sidnumrerade data och totaler

  3. MongoDB - Skapa en databas

  4. Hur skiljer sig aerospike från andra nosql-databaser med nyckel-värden?