-
Type:
Bug
-
Resolution: Done
-
Priority:
Major - P3
-
None
-
Affects Version/s: 2.4.4
-
Component/s: LINQ
-
None
-
Environment:Windows
-
None
-
None
-
None
-
None
-
None
-
None
-
None
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"); } } } }