0

配列のみを含むオブジェクトがあるとしましょう

public class A 
{
       [BsonId]
       public ObjectId Id;
       public int[] arr;

       public A()
       {
            arr = new [5];
       }

}

配列内の特定のインデックスを Id で更新したい場合、

Idが見つかりませんでした新しいオブジェクトをデータベースに挿入したいのですが、挿入されたとき

この提供された Id と、提供されたインデックスに提供された値を持つ arr があると想定されます。

これまでのところとても良いですが、それは起こりません。

//receiving ObjectId id, int input_index, int input_value

var filter = Builders<A>.Filter.Eq(x => x.Id, id);
var options = new UpdateOptions()
{
    IsUpsert = true
};
var update = Builders<A>.Update.Set(x => x.arr[input_index], input_value);

//executing the query....

代わりに、Id は正常に挿入されますが、配列は配列ではなく、提供された値を持つ int 値になります。

それは既知のバグですか?とにかくその周りにありますか?

ティア

古い質問の参照ですが、2年前のことです: こちら

編集

デフォルトの値でarrを登録しています:

if (!BsonClassMap.IsClassMapRegistered(typeof (A)))
            {
                BsonClassMap.RegisterClassMap<A>(map =>
                {
                    map.AutoMap();
                    map.SetIgnoreExtraElements(true);
                    map.GetMemberMap(c => c.arr)
                        .SetDefaultValue(new int[5] {0, 0, 0, 0, 0});
                });
            }

また、registerMap の代わりにタグを追加しようとしました:

[BsonDefaultValue(new int[5] {0, 0, 0, 0, 0})]
[BsonIgnoreIfDefault]
public int[] arr {set;get;}

そして私は受け取っています:

クラス DatabaseManager.MongoEntities.A の arr プロパティをデシリアライズ中にエラーが発生しました: BsonType 'Document' から 'int[]' をデシリアライズできません。

4

1 に答える 1

1

クエリによっては、配列ではなく整数として格納されているという事実は問題にならない場合があります。

次のコレクションを検討してください。

/* 1 */
{
    "_id" : ObjectId("56faeabd4e7309356aa1a0ba"),
    "arr" : [ 
        1, 
        2, 
        3
    ]
}

/* 2 */
{
    "_id" : ObjectId("56faeac74e7309356aa1a0bb"),
    "arr" : 2
}

次のように、 containsタイプのクエリは引き続き期待どおりに機能します。

db.collection.find({arr: 2})

それでも、これらの両方のドキュメントを返します。

などの他$pushの配列っぽい更新を行いたい場合、問題が発生します。$pop$size

シリアライザー

型へのカスタム逆シリアル化の例を次に示します。

using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver;

class Program
{
    static void Main(string[] args)
    {
        BsonSerializer.RegisterSerializer(new MySerializer());

        var client = new MongoClient();
        var database = client.GetDatabase("test");
        var collection = database.GetCollection<A>("upsertArray");

        var docs = collection.Find(new BsonDocument()).ToList();
    }
}

class A
{
    public int[] Arr { get; set; }
    public ObjectId Id { get; set; }
}

class MySerializer : SerializerBase<A>
{
    public override A Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var doc = BsonDocumentSerializer.Instance.Deserialize(context);

        var ints = new int[5];

        var arr = doc["arr"];

        if (arr.IsBsonArray)
        {
            var array = arr.AsBsonArray;

            for (var i = 0; i < 5; i++)
            {
                if (i < array.Count)
                {
                    ints[i] = array[i].AsInt32;
                }
                else
                {
                    break;
                }
            }
        }
        else
        {
            ints[0] = arr.AsInt32;
        }

        return new A { Arr = ints, Id = doc["_id"].AsObjectId };
    }
}
于 2016-03-29T20:57:08.937 に答える