sql >> Database teknologi >  >> NoSQL >> MongoDB

Deserialiseringsfelt, når typen ændres ved hjælp af MongoDb csharp-driver

Der er et par ting i gang. Den vigtigste er, at du skal forbruge input uanset type, ellers bliver deserialiseringsprocessen ude af sync. Jeg har testet dit scenario ved at skrive en brugerdefineret serializer kaldet ZipCodeSerializer, som håndterer nuller og skriver postkoder som strenge, men accepterer enten streng eller ints på input og konverterer ints til streng.

Jeg brugte denne klasse til at teste:

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

Og dette er den brugerdefinerede serializer, jeg skrev:

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

Du skal sikre dig, at den brugerdefinerede serializer er tilsluttet, hvilket du kan gøre sådan her:

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

Så nu vil postkodefeltet i adresseklassen blive håndteret af den brugerdefinerede serializer.

Jeg oprettede nogle testdata ved hjælp af BsonDocument for at gøre det nemt at tvinge bestemte lagrede versioner af dataene i min testsamling:

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

Sådan så dokumenterne ud med mongo-skallen:

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

så vi ser, at nogle postkoder er strenge, og nogle er ints (der er også indsat et nul).

Og dette er min testkode:

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

Og outputtet af at køre testkoden er:

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

Bemærk, at det postnummer, der var en int i databasen, nu er en streng.

Den fulde kildekode til mit testprogram er tilgængelig på:

http://www.pastie.org/3775465




  1. Opretter forbindelse til MongoDB replikasæt med rmongodb

  2. mongoDB kort/reducere minus reducere

  3. Er der nogen måde at atomisk opdatere to samlinger i MongoDB?

  4. MongoDB Indsæt nøgle med '$' (dollar)