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

Projecting from and to the same type including the _id field causes deserialization to fail

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Minor - P4 Minor - P4
    • 2.17.0
    • Affects Version/s: 2.2
    • Component/s: Linq, LINQ3
    • Fully Compatible

      When using: yourMongoCollection.AsQueryable().Select(projectionExpression).ToList() in versions greater than 2.1.X it fails.

      The examples below just call Count() for demonstration purposes.

      Program.cs
          internal class Program
          {
              internal class Person
              {
                  public Guid Id { get; set; }
                  public string Name { get; set; }
              }
      
              private static void Main(string[] args)
              {
                  // RegisterConventions
                  var conventionPack = new ConventionPack
                  {
                      new IgnoreIfNullConvention(true),
                      new NoIdMemberConvention()
                  };
                  ConventionRegistry.Register("GlobalConventions", conventionPack, t => true);
      
                  // Mapping People collection
                  var map = BsonClassMap.RegisterClassMap<Person>();
                  map.AutoMap();
                  map.MapProperty(c => c.Id).SetIsRequired(true);
                  map.SetIdMember(map.GetMemberMap(c => c.Id));
      
                  // Creating mongo client and dropping collection
                  var mongoClient = new MongoClient("mongodb://buildbee");
                  var mongoDatabase = mongoClient.GetDatabase("db");
                  mongoDatabase.DropCollectionAsync("people").Wait();
                  var peopleCollection = mongoDatabase.GetCollection<Person>("people");
                  
                  // one document is inserted
                  peopleCollection.InsertOneAsync(new Person
                  {
                      Id = Guid.NewGuid(),
                      Name = "A"
                  }).Wait();
      
                
                  DoIt("1- Count", () => peopleCollection.AsQueryable().Count());
      
                  DoIt("2- ToList Without Select", () => peopleCollection.AsQueryable().ToList().Count);
      
                  DoIt("3.1- ToList With Select", () => peopleCollection.AsQueryable().Select(p => p).ToList().Count);
      
                  DoIt("3.2- ToList With Select", () => peopleCollection.AsQueryable().Select(p => new Person
                  {
                      Id = p.Id,
                      Name = p.Name,
                  }).ToList().Count);
      
                  DoIt("3.3- ToList With Select", () => peopleCollection.AsQueryable().Select(p => new Person
                  {
                      Id = p.Id,
                      // Name = p.Name,
                  }).ToList().Count);
      
                  DoIt("3.4- ToList With Select", () => peopleCollection.AsQueryable().Select(p => new Person
                  {
                      // Id = p.Id,
                      Name = p.Name,
                  }).ToList().Count);
              }
      
              private static void DoIt(string message, Func<int> countQuery)
              {
                  try
                  {
                      Console.WriteLine(message);
                      Console.WriteLine(countQuery());
                  }
                  catch (Exception e)
                  {
                      Console.WriteLine(e);
                  }
                  Console.WriteLine();
              }
          }
      
      Execution output using .NEt Driver 2.1.1 or 2.1.0

      1- Count
      1

      2- ToList Without Select
      1

      3.1- ToList With Select
      1

      3.2- ToList With Select
      1

      3.3- ToList With Select
      1

      3.4- ToList With Select
      1

      Press any key to continue . . .

      Execution output using .NEt Driver 2.2.0 or greater

      1- Count
      1

      2- ToList Without Select
      1

      3.1- ToList With Select
      1

      3.2- ToList With Select
      System.FormatException: Element 'Id' does not match any field or property of class ConsoleApplication1.Program+Person.
      at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Execute(Expression expression)
      at MongoDB.Driver.Linq.MongoQueryableImpl`2.GetEnumerator()
      at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
      at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
      at ...

      3.3- ToList With Select
      System.FormatException: Element 'Id' does not match any field or property of class ConsoleApplication1.Program+Person.
      at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Execute(Expression expression)
      at MongoDB.Driver.Linq.MongoQueryableImpl`2.GetEnumerator()
      at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
      at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
      at ...

      3.4- ToList With Select
      System.FormatException: Required element '_id' for property 'Id' of class ConsoleApplication1.Program+Person is missing.
      at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Execute(Expression expression)
      at MongoDB.Driver.Linq.MongoQueryableImpl`2.GetEnumerator()
      at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
      at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
      at ...

      Press any key to continue . . .

            Assignee:
            robert@mongodb.com Robert Stam
            Reporter:
            suikevil Roberto PĂ©rez
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: