2015-11-25 3 views
0

Я столкнулся с тем, что я могу понять только как ошибку в драйвере C#.Добавление OfType <T> на MongoCollection «нарушает» поведение UpdateOneAsync

Это gist иллюстрирует проблему.

Если я бегу

collection.UpdateOneAsync(
    "{ \"_id\" : ObjectId(\"5656277cd4d37b13b4e7e009\"), \"Addresses.Index\" : 4 }, 
    "{ \"$set\" : { \"Addresses.$\" : { \"_t\" : [\"Address\", \"EmailAddress\"], \"Index\" : 4, \"MailTo\" : \"[email protected]\" } } }") 

я получить желаемый результат.

Если же я использую строителей, чтобы построить определение фильтра и определение обновления, как так:

var filter = Builders<Person> .Filter .And(Builders<Person>.Filter.Eq(p => p.Id, person.Id), Builders<Person>.Filter.Eq("Addresses.Index", 4));

var update = Builders<Person>.Update.Set("Addresses.$", new EmailAddress { Index = 4, MailTo = "[email protected]" });

, то я должен изменить свой призыв обновить быть

await collection.OfType<Person>().UpdateOneAsync(filter, update);

и вызов toType приводит к неправильному addre ss заменяется.

+0

- это коллекция 'IQueryable ' или 'IEnumerable '? Готов поспорить, это IQueryable. –

+0

коллекция IMongoCollection

+0

О, хорошо. Поэтому он использует ['IMongoCollection.OfType '] (http://api.mongodb.org/csharp/current/html/M_MongoDB_Driver_IMongoCollection_1_OfType__1.htm), а не ['Enumerable.OfType '] (https: // msdn. microsoft.com/en-us/library/bb360913(v=vs.100).aspx) или ['Queryable.OfType '] (https://msdn.microsoft.com/en-us/library/bb344857 (v = vs.100) .aspx). Тогда нет идеи. –

ответ

1

Это не связано с драйвером C# MongoDB, но, похоже, это ошибка в MongoDB, когда тип используется в запросе.

Вы можете видеть, что это приводит к тому же вопросу без использования OfType, но указав поле типа явно (т.е. "_t"):

var filter = Builders<Person>.Filter.And(
    new BsonDocument("_t", "Person"), 
    Builders<Person>.Filter.Eq(p => p.Id, person.Id), 
    Builders<Person>.Filter.Eq("Addresses.Index", 4)); 
var update = Builders<Person>.Update.Set(
    "Addresses.$", 
    new EmailAddress { Index = 4, MailTo = "[email protected]" }); 
await db.GetCollection<Person>("Objects").UpdateOneAsync(filter, update); 

Вы можете увидеть запрос это будет генерировать этот кусок кода:

Console.WriteLine(db.GetCollection<Person>("Objects").Find(filter)); 

И запрос состоит в следующем, который совершенно правильно:

{ "_t" : "Person", "_id" : ObjectId("5656356f64c22e5d38aeb92e"), "Addresses.4 } 
+1

Проблема может заключаться в том, что дискриминатор сохраняется как массив и соответствует второму элементу массива _t ... И оператор позиционирования ($) в update использует эту позицию в инструкции обновления. –

+0

@CraigWilson кажется очень вероятным. Он действительно не воспроизводится, когда '_t' является просто полем. – i3arnon

Смежные вопросы