[CSHARP-2825] Logical Negation Operator and Comparing False Have Different Results Created: 29/Oct/19  Updated: 27/Oct/23  Resolved: 11/Nov/19

Status: Closed
Project: C# Driver
Component/s: Linq
Affects Version/s: 2.9.2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Christopher McEwen Assignee: Dmitry Lukyanov (Inactive)
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Comparing a property to false using the Equality Comparer gives different results to using the Logical Negation Operator on the property.

See the following code snippet...

 

using Mongo2Go;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Driver;
using MongoDB.Driver.Linq;namespace ConsoleApp11
{
    class Program
    {
        static void Main(string[] args)
        {
            using (MongoDbRunner mongoRunner = MongoDbRunner.Start())
            {
                // Ignore the default values. So a false boolean will not be stored in Mongo
                ConventionRegistry.Register("Ignore default values", new ConventionPack { new IgnoreIfDefaultConvention(true) }, t => true);                
 var mongoClient = new MongoClient(mongoRunner.ConnectionString);                
var mongoDb = mongoClient.GetDatabase("TestDb");               
 var collection = mongoDb.GetCollection<SimpleDocument>("TestCollection");               
 var documentTwo = new SimpleDocument
                {
                    Property = false
                };                collection.InsertOne(documentTwo);                
var query1 = collection.AsQueryable().Where(x => x.Property == false).ToList(); // Doesn't find the record         
       var query2 = collection.AsQueryable().Where(x => !x.Property).ToList(); // Finds the record
            }
        }
    }    public class SimpleDocument
    {
        public ObjectId Id { get; set; }
        public bool Property { get; set; }
    }
}

I would have expected both query1 and query2 to find the record.

 



 Comments   
Comment by Christopher McEwen [ 11/Nov/19 ]

Would you not expect these two queries to generate the same query though, I certainly would?

For instance, if I used a SQL Linq provider using == or ! then it would generate...

WHERE Property = 0

for both queries.

 

 

Comment by Dmitry Lukyanov (Inactive) [ 11/Nov/19 ]

Hello chrismcewan@ncfe.org.uk

Our LINQ implementation assumes the query field exists in the document. The case when the field doesn't exist in the document is out of the scope of our implementation.

Comment by Christopher McEwen [ 29/Oct/19 ]

Just to add to this..

query1 generates this...

aggregate([{ "$match" : { "Property" : false } }])

query2 generates this...

aggregate([{ "$match" : { "Property" : { "$ne" : true } } }])

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