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

Queries using AsQueryable() with dot notation and nullable types do not work

    XMLWordPrintableJSON

Details

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major - P3 Major - P3
    • 2.4.3
    • 2.3
    • Linq
    • None
    • Windows

    Description

      Good morning,

      We have encountered an error that does not let us keep working without changing our Model.

      Our test model to reproduce the bug:

          public class Car
          {
              public Guid Id { get; set; }
              public ExtraInfo ExtraInfo { get; set; }
          }
       
          public class ExtraInfo
          {
              public int NotNullableType { get; set; }
              public int? Type { get; set; }
          }
      

      The issue:

      private static void Test(MongoDbCollection<Car> mongoDbCollection)
              {
                  var queryable = mongoDbCollection.AsQueryable();
       
                  // 1 - Both paths are correct
                  queryable.Where(c => c.ExtraInfo.Type == 1 && c.ExtraInfo.NotNullableType == 1).ToList();
                  
                  // 2 - Path is correct
                  queryable.Where(c => c.ExtraInfo.Type == null).ToList();
       
                  // 3 - Path is incorrect (.Value breaks something)
                  queryable.Where(c => c.ExtraInfo.Type.Value == 2).ToList();
       
                  // 4 - Path is incorrect (.Value keeps breaking something)
                  int? infoType = 3;
                  queryable.Where(c => c.ExtraInfo.Type.Value == infoType).ToList();
       
                  // 5 - Path is correct when not nullable type only. "list.Contains()" method signature requires to use ".Value" when it is a nullable
                  var list = new List<int>
                  {
                      4, 5
                  };
                  queryable.Where(c => list.Contains(c.ExtraInfo.Type.Value) || list.Contains(c.ExtraInfo.NotNullableType)).ToList();
              }
      

      And the mongo query translations are these ones:

      // 1 - Both paths are correct
        "command" : {
          "aggregate" : "cars",
          "pipeline" : [{
              "$match" : {
                "ExtraInfo.Type" : 1,
                "ExtraInfo.NotNullableType" : 1
              }
            }]
        }
          
      // 2 - Path is correct
        "command" : {
          "aggregate" : "cars",
          "pipeline" : [{
              "$match" : {
                "ExtraInfo.Type" : null
              }
            }]
        }
        
      // 3 - Path is incorrect (.Value breaks something)
        "command" : {
          "aggregate" : "cars",
          "pipeline" : [{
              "$match" : {
                "Type" : 2
              }
            }]
        }
        
      // 4 - Path is incorrect (.Value keeps breaking something)
        "command" : {
          "aggregate" : "cars",
          "pipeline" : [{
              "$match" : {
                "Type" : 3
              }
            }]
        }
       
      // 5 - Path is correct when not nullable type only. "list.Contains()" method signature requires to use ".Value" when it is a nullable
        "command" : {
          "aggregate" : "cars",
          "pipeline" : [{
              "$match" : {
                "$or" : [{
                    "Type" : {
                      "$in" : [4, 5]
                    }
                  }, {
                    "ExtraInfo.NotNullableType" : {
                      "$in" : [4, 5]
                    }
                  }]
              }
            }]
        }
      

      Hope it helps to find the problem,

      Thanks!

      Attachments

        Activity

          People

            robert@mongodb.com Robert Stam
            suikevil Roberto Pérez
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: