Details
-
Bug
-
Resolution: Done
-
Major - P3
-
None
-
2.4.4
-
None
-
Windows
Description
When using UpdateDefinitionBuilder<> to update field parsing in an anonymous type as "object", it will fail to update the field correctly - introducing _t and _v.
This issue relates to CSHARP-1957
Attached is Program.cs that exposes this issue.
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using MongoDB.Bson;
|
using MongoDB.Bson.Serialization;
|
using MongoDB.Driver;
|
|
|
namespace Mongo.Test
|
{
|
|
|
public class Person |
{
|
public string Name { get; set; } |
public char Gender { get; set; } |
public override string ToString() => $@"{GetType().Name}: ({Gender}) {Name}"; |
}
|
|
|
|
|
public class Group |
{
|
public ObjectId Id { get; set; } = new ObjectId(); |
public string Name { get; set; } |
public List<Person> Members { get; set; } |
public override string ToString() => $@"{GetType().Name}: {Id}, Name: {Name}, Members: [{string.Join(", ", Members)}]"; |
}
|
|
|
|
|
class Program |
{
|
static void Main() |
{
|
var mongoUrl = MongoUrl.Create(@"mongodb://localhost/test"); |
var client = new MongoClient(mongoUrl); |
client.DropDatabase(mongoUrl.DatabaseName);
|
var database = client.GetDatabase(mongoUrl.DatabaseName);
|
var collection = database.GetCollection<Group>(nameof(Group));
|
|
|
var group = new Group |
{
|
Name = "Class A1", |
Members = new List<Person> |
{
|
new Person { Name ="Lea", Gender = 'F' } |
}
|
};
|
collection.InsertOne(group);
|
var result = collection.Find(g => g.Members.Any(p => p.Gender == 'F')).FirstOrDefault(); |
Console.WriteLine(result); // #1: Document added perfectly |
|
|
group.Members.AddRange(new List<Person> |
{
|
new Person { Name ="Linus", Gender = 'M' }, |
new Person { Name ="Julius", Gender = 'M' } |
});
|
UpdateMemebrs(collection, group.Id, group.Members); // #2: Document updated perfectly |
|
|
group.Members.Add(new Person { Name = "Martin", Gender = 'M' }); |
|
|
// #3.1: Updating members using reflection to get property value... |
var propertyInfo = typeof(Group).GetProperty("Members"); |
UpdateMemebrs(collection, group.Id, propertyInfo.GetValue(group)); // NOTE: the "Members" field is actually of type List<Person> but we are parsing <object> |
// #3.2: ...will "change" the document so find does not work |
|
|
Console.ReadLine();
|
}
|
|
|
|
|
private static void UpdateMemebrs<TProp>(IMongoCollection<Group> collection, ObjectId groupId, TProp members) |
{
|
var filter = Builders<Group>.Filter.Eq(p => p.Id, groupId);
|
var update = Builders<Group>.Update.Set(nameof(Group.Members), members);
|
Console.WriteLine(update.Render(BsonSerializer.LookupSerializer<Group>(), BsonSerializer.SerializerRegistry));
|
collection.UpdateOne(filter, update);
|
|
|
// Now, test that the update was good |
var result = collection.Find(g => g.Members.Any(p => p.Gender == 'F')).FirstOrDefault(); |
Console.WriteLine(result?.ToString() ?? "Not Found"); |
}
|
}
|
}
|
}
|