-
Notifications
You must be signed in to change notification settings - Fork 494
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HasValue LINQ translated as IS_DEFINED instead of IS_DEFINED AND NOT IS_NULL #2248
Comments
@timsander1 or @sboshra can you take a look? |
This is the correct behavior. Null is a valid JSON value. |
Sorry @timsander1 but I haven't understood. Let's make an example. Given the following Class for documents stored in Cosmos:
In this case the following LINQ query will get all the data where FooData is null:
This LINQ will be translated as "SELECT * FROM c WHERE NOT IS_DEFINED(c.fooData)" and this will match all my documents because them are translated as:
But if I changed the serialization mode into:
the same LINQ query will not work because the JSON document will be serialiez as:
Is this the desired behavior? Should I change the LINQ query based on how I serialize the data?
|
That makes sense and this is the desired behavior (not a bug). If you want null values to be omitted from the item, can you set NullValueHandling.Ignore, like you mentioned? Is that reasonable? |
My point is different. My app created a series of documents (in production) with a serialized property that in some cases could have NULL value. In a new version of the same application I decide to change the serialization of that property and add the decorator NullValueHandling.Ignore. Am I now responsible to remember that the meaning of HasValue for the Cosmos SDK doesn't manage the defined null property?. So from now on I should write a query like the following one to manage both cases:
That where condition is a no-sense in C# code. |
Null and undefined are different in JSON. This is an attribute of JSON, more than Cosmos DB specifically. Like you mentioned, this is important to remember. Here's a doc that walks through the differences between null and undefined in queries: https://devblogs.microsoft.com/cosmosdb/difference-between-null-and-undefined/ A property can be defined and have a null value. In this case, it has a value (the value is null). LINQ in Cosmos DB is consistent with this definition. If you want null values to be ignored, setting NullValueHandling.Ignore is a good solution. |
At Cosmos level it's fine, I thinked about this possibility. But at SDK level it is a strange behaviour. |
The issue is c# doesn't have a concept of undefined like JSON does. Using the linq extension might help with readability. var iter = _container.GetItemLinqQueryable<Foo>()
.Where(foo => !foo.FooData.IsNull() && !foo.FooData.IsDefined())
.ToFeedIterator();
while(iter.HasMoreResults)
{
var result = await iter.ReadNextAsync();
} |
Yes, this will definitely help. But 'HasValue' is supported from the SDK and its translation is misleading in this specific case. |
Hi @Ettores88, I agree with that! The mapping of C# -> JSON concepts is confusing here. This great feedback to have when we plan the next major SDK release and can make significant changes. |
azure-cosmos-dotnet-v3/Microsoft.Azure.Cosmos/src/Linq/ExpressionToSQL.cs
Lines 751 to 755 in df040f3
Shouldn't be translated as "IS_DEFINED() AND NOT IS_NULL()" ?
The behaviour in code change if I use the "NullValueHandling = NullValueHandling.Ignore" or the "NullValueHandling = NullValueHandling.Include" but from an object point of view in the end it is still null and doesn't have a value.
The text was updated successfully, but these errors were encountered: