在 MongoCollection "breaks" 上添加 OfType<T> UpdateOneAsync 的行为

Adding OfType<T> on MongoCollection "breaks" the behaviour of UpdateOneAsync

我 运行 我只能理解为 C# 驱动程序中的错误。

gist 说明了问题。

如果我运行

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

我得到了想要的结果。

但是,如果我像这样使用构建器来构建过滤器定义和更新定义:

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 = "Never@home.com" });

然后我必须将更新调用更改为

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

并且对 OfType 的调用导致错误的地址被替换。

这与 MongoDB C# 驱动程序无关,但在查询中使用该类型时,它似乎是 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 = "Never@home.com" });
await db.GetCollection<Person>("Objects").UpdateOneAsync(filter, update);

您可以看到使用这段代码生成的查询:

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

下面的查询是完全正确的:

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