2016-03-24 2 views
0

Допустим, у меня есть объект, который содержит только массивC# MongoDB upsert с позиционной оператора выдает

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

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

} 

, когда я хочу, чтобы обновить определенный индекс в массиве с помощью Id,

и не мог Id Не будет найден. Я хочу вставить новый объект в db, и когда он вставлен

Предположим, что этот предоставленный Идентификатор и 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 значение с значением параметра, вместо массива.

Это известная ошибка? все равно вокруг?

ТИА

Refrence для старого вопроса, но это было 2 года назад: here

EDIT

Im регистрации обр с умолчанию вальса:

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

и Im получение:

Произошла ошибка при десериализации обр свойство класса DatabaseManager.MongoEntities.A: Не удается десериализации 'ИНТ []' из 'Документ' BsonType.

+0

Я предполагаю, что если в массиве нет 5 элементов, то заполняются только те, которые присутствуют, и любые избытки игнорируются? – BanksySan

ответ

1

В зависимости от вашего запроса факт, что он хранится как целое число вместо массива, может не иметь значения.

Рассмотрим коллекцию:

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

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

содержит запросы типа все еще работает, как ожидалось, например .:

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

Тем не менее возвращает оба эти документы.

Проблемы возникли бы в том, что вы хотели сделать другие обновления массива-ish, например $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 }; 
    } 
} 
+0

это создает проблемы, потому что он не может отнести документ к фактическому типу, в этом примере: A –

+0

@OriRefael Ah ... да, вам понадобится собственный сериализатор. – BanksySan

+0

@OriRefael Просто добавленный код для пользовательского десериализатора. Это поведение, о котором вы думали? – BanksySan