[CSHARP-2674] string.IsNullOrEmpty is false when field does not exist. Created: 01/Aug/19  Updated: 28/Oct/23  Resolved: 15/Feb/22

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

Type: Bug Priority: Major - P3
Reporter: Richard Collette Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: rp-track
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to CSHARP-4057 LinqV3 Null Coalescing operator with ... Closed
Epic Link: CSHARP-3615

 Description   

Driver version 2.8.2

string.isNullOrEmpty utilizes a test for null equality using

                           "$or":[
                              {
                                 "$eq":[
                                    "$someField",
                                    null
                                 ]
                              },
                              {
                                 "$eq":[
                                    "$someField",
                                    ""
                                 ]
                              }
                           ]
                        }

However, if the field is not present, the null equality operation returns false.

The null coalescing operator (??) on the other hand does work with both nulls and non-existing fields, and uses the $ifNull operation rather than equality.

"Url":{
               "$ifNull":[
                  "$shopUrl",
                  "$typeUrl"
               ]
            },

It seems that $ifNull would be a better operation to use in the composed string.IsNullOrEmpty() method.

Without this, we have to resort to strange expressions like:

isExternalUrl = string.IsNullOrEmpty((pt.ShopUrl ?? "")),

If I don't use the null coalescing operator in that example, the evaluation will return false when the field does not exist.



 Comments   
Comment by James Kovacs [ 15/Feb/22 ]

This issue has been fixed in the new LINQ provider (known as LINQ3), which is included in the 2.14 release.

Configure your MongoClientSettings to use LinqProvider.V3 if you want to use this functionality.

To configure a client to use the LINQ3 provider use code like the following

var connectionString = "mongodb://localhost";
var clientSettings = MongoClientSettings.FromConnectionString(connectionString);
clientSettings.LinqProvider = LinqProvider.V3;
var client = new MongoClient(clientSettings);

Comment by Richard Collette [ 23/Aug/19 ]

While the null coalescing operator (??) will work in a .Project() lambda expression, it does not work in a LINQ query (which seems odd).

This makes this issue a blocker for LINQ queries.

So this does not work for me.

var query =
                // Unfortunately, AsQueryable is an extension method rather than an interface implementation
                // defined on IMongoDbCollection, otherwise LINQ would not require us to call AsQueryable().
                // WhereText is a 2 line extension method since FullText search requires injecting a filter normally.
                from productType in _productTypes.AsQueryable().WhereText(searchText)
                where !(string.IsNullOrEmpty(productType.ShopUrl ?? "") &&
                        string.IsNullOrEmpty(productType.TypeUrl ?? ""))
                group productType by productType.ProductFamilyId // The by clause becomes the key of the group
                into productFamilyGroup
                join productFamily in _productFamilies.AsQueryable() on productFamilyGroup.Key
                    equals productFamily
                        .ProductFamilyId
                select new ProductTypeSearchFamily
                {
                    Name = productFamily.Name, ProductFamilyId = productFamily.ProductFamilyId
                };

 

 

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