MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Десериализиращо поле, когато типът се промени с помощта на MongoDb csharp драйвер

Случват се няколко неща. Основният е, че трябва да консумирате входа независимо от типа или процесът на десериализация излиза от синхрон. Тествах вашия сценарий, като написах персонализиран сериализатор, наречен ZipCodeSerializer, който обработва нули и записва ZipCodes като низове, но приема или низ, или int при въвеждане и преобразува int в низ.

Използвах този клас за тестване:

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

И това е персонализираният сериализатор, който написах:

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

Трябва да се уверите, че персонализираният сериализатор е свързан, което можете да направите по следния начин:

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

Така че сега полето ZipCode на класа Address ще се обработва от персонализирания сериализатор.

Създадох някои тестови данни с помощта на BsonDocument, за да улесня форсирането на конкретни съхранени версии на данните в моята тестова колекция:

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

Ето как изглеждаха документите с помощта на mongo shell:

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

така че виждаме, че някои пощенски кодове са низове, а други са int (също има добавена нула).

А това е моят тестов код:

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

И резултатът от изпълнението на тестовия код е:

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

Забележете, че пощенският код, който беше int в базата данни, сега е низ.

Пълният изходен код на моята тестова програма е достъпен на:

http://www.pastie.org/3775465




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB:java.lang.IllegalStateException:състоянието трябва да бъде:отворено

  2. MongoDB проекция на вложени масиви

  3. mongoDB:C# драйвер V2 Как да актуализирате елемент във вложена колекция

  4. ArrayFilter в mongoose

  5. Заявката е неуспешна с код за грешка 13 и съобщение за грешка „не е упълномощен на [db] да изпълни команда { find: