sql >> Database >  >> NoSQL >> MongoDB

Veld deserialiseren wanneer type wordt gewijzigd met MongoDb csharp-stuurprogramma

Er zijn een paar dingen aan de hand. De belangrijkste is dat u de invoer moet gebruiken, ongeacht het type, anders loopt het deserialisatieproces niet synchroon. Ik heb je scenario getest door een aangepaste serializer te schrijven met de naam ZipCodeSerializer die nulls verwerkt en ZipCodes als strings schrijft, maar string of ints accepteert bij invoer en de ints converteert naar string.

Ik heb deze les gebruikt om te testen:

public class Address
{
    public ObjectId Id;
    public string ZipCode;
}

En dit is de aangepaste serializer die ik schreef:

public class ZipCodeSerializer : BsonBaseSerializer
{
    public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
    {
        var bsonType = bsonReader.CurrentBsonType;
        switch (bsonType)
        {
            case BsonType.Null:
                bsonReader.ReadNull();
                return null;
            case BsonType.String:
                return bsonReader.ReadString();
            case BsonType.Int32:
                return bsonReader.ReadInt32().ToString();
            default:
                var message = string.Format("ZipCodeSerializer expects to find a String or an Int32, not a {0}.", bsonType);
                throw new BsonSerializationException(message);
        }
    }

    public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
    {
        if (value == null)
        {
            bsonWriter.WriteNull();
        }
        else
        {
            bsonWriter.WriteString((string)value);
        }
    }
}

U moet ervoor zorgen dat de aangepaste serializer is aangesloten, wat u als volgt kunt doen:

BsonClassMap.RegisterClassMap<Address>(cm =>
    {
        cm.AutoMap();
        cm.GetMemberMap(a => a.ZipCode).SetSerializer(new ZipCodeSerializer());
    });

Dus nu wordt het postcodeveld van de adresklasse afgehandeld door de aangepaste serializer.

Ik heb enkele testgegevens gemaakt met behulp van BsonDocument om het gemakkelijk te maken bepaalde opgeslagen versies van de gegevens in mijn testverzameling te forceren:

collection.Drop();
collection.Insert(new BsonDocument());
collection.Insert(new BsonDocument("ZipCode", BsonNull.Value));
collection.Insert(new BsonDocument("ZipCode", "12345"));
collection.Insert(new BsonDocument("ZipCode", 56789));

Zo zagen de documenten eruit met de mongo-shell:

> db.test.find()
{ "_id" : ObjectId("4f871374e447ad238040e346") }
{ "_id" : ObjectId("4f871374e447ad238040e347"), "ZipCode" : null }
{ "_id" : ObjectId("4f871374e447ad238040e348"), "ZipCode" : "12345" }
{ "_id" : ObjectId("4f871374e447ad238040e349"), "ZipCode" : 56789 }
>

dus we zien dat sommige postcodes strings zijn en sommige ints (er wordt ook een null in gegooid).

En dit is mijn testcode:

foreach (var document in collection.FindAll())
{
    Console.WriteLine(document.ToJson());
}

En de uitvoer van het uitvoeren van de testcode is:

{ "_id" : ObjectId("4f871374e447ad238040e346"), "ZipCode" : null }
{ "_id" : ObjectId("4f871374e447ad238040e347"), "ZipCode" : null }
{ "_id" : ObjectId("4f871374e447ad238040e348"), "ZipCode" : "12345" }
{ "_id" : ObjectId("4f871374e447ad238040e349"), "ZipCode" : "56789" }
Press Enter to continue

Merk op dat de postcode die een int was in de database nu een string is.

De volledige broncode van mijn testprogramma is beschikbaar op:

http://www.pastie.org/3775465




  1. Problemen bij het publiceren/abonneren op een Mongo-geaggregeerde query

  2. Een alleen-lezen verbinding maken met pymongo

  3. Verbinding maken met mongodb via de browser?

  4. mongodb hoe alleen een waardelijst te retourneren van zoekquery