[CSHARP-1892] Queries using AsQueryable() with dot notation and nullable types do not work Created: 13/Jan/17  Updated: 06/Mar/17  Resolved: 06/Mar/17

Status: Closed
Project: C# Driver
Component/s: Linq
Affects Version/s: 2.3
Fix Version/s: 2.4.3

Type: Bug Priority: Major - P3
Reporter: Roberto Pérez Assignee: Robert Stam
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

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!



 Comments   
Comment by Githook User [ 06/Mar/17 ]

Author:

{u'username': u'rstam', u'name': u'rstam', u'email': u'robert@robertstam.org'}

Message: CSHARP-1892: Code review changes and added more tests.
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/d57fe7f302f489c253d20caf657e68756093cb20

Comment by Githook User [ 06/Mar/17 ]

Author:

{u'username': u'rstam', u'name': u'rstam', u'email': u'robert@robertstam.org'}

Message: CSHARP-1892: Fix a scenario that was not using the full dotted field name for an embedded field.
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/d1d2127b10e5782d0b64aac065b7bb158d5d0152

Generated at Wed Feb 07 21:40:57 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.