Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-1998

UpdateDefinitionBuilder fails when updating enumerable field type with "object"

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 2.4.4
    • Component/s: Linq
    • Labels:
      None
    • Environment:
      Windows

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

            Assignee:
            Unassigned Unassigned
            Reporter:
            marloe Martin Lobger
            Votes:
            2 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: