-
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
Bad LINQ to SQL translation for filter on non-nullable boolean property #682
Comments
I would argue this behaving correctly. If you look at the ECMA standards undefined is not equal to false. Here is a related stackoverflow question. c# the closes thing to undefined is null. A nullable bool that is null is not equal to false.
What you are looking for is here.
|
Hi @j82w, I agree that undefined isn't equal to false, however in this scenario, the query is driven by the C# model, where the I'm aware of the |
Hi @thomaslevesque , That's a good point. @kirankumarkolli what is your opinion? |
I agree. We're running into this in our design too. We abstract out the Cosmos stuff but still need to educate devs and remind ourselves that "It might look like C#, but it's actually JSON so use But I'm opinionated just because of the path we chose. So even though I agree, I kinda would be worried about special-casing this. Also because of the path we chose (Type discrimination and exposing IQueryable) :) Because what if there's two types of C# documents you're storing? One has your
If I'm using a Further, what if it's an int instead? The default value in C# is zero. But what if I want to filter for when there's actually a zero in the document? |
Isn't default-value after desalinization is also implementation dependent (ex: default value, default constructor). |
The data and the data model don't match in this case (if the C# model is used to create data then we should only have boolean values for the property). It seems there're multiple versions of data (before and after IsDeleted is introduced). That means the scenario to filter on only the data set which has IsDeleted set to false is valid. Translating !IsDeleted to both false equality and undefined assumes these two are equivalent (or implementation depended as Kiran mentioned above). Consider the scenario where we have a property called IsNotDeleted, which has an opposite value of the IsDeleted property. Should we include undefined when filtering on IsNotDeleted = true? it depends on the scenario's definition of the undefined. So undefined can't seem to be implied with a particular value of the boolean property. |
For the case where data model changes like in this issue, it seems there're a few options:
|
It depends on which type you're querying with. If the type has a non-nullable
But in this case, shouldn't you filter on the
I don't think that's a very common scenario. If the property is not nullable in the C# model, you don't expect the field to be missing in the document ; and if it is missing, the value would be set to 0 in the C# object on deserialization anyway. If you really need to filter documents that do have an explicit value, you can always do it in SQL.
Yes, but it doesn't really matter, I think. What matters here is the semantics of the model type you're using in the query. If a property is not nullable in the C# model, you shouldn't have to worry about whether it's present in the document or not.
Indeed, it's a case where the
That's a fair point. I didn't think about that. But maybe it could be handled with a I realize it all seems unnecessarily complex, but the scenario I described is probably quite common, and having to specify |
So in this case because the data and the model doesn't match, the specific behavior has to be specified. If we opt for a specific default behavior, it could lead to a different kind of confusion as in my previous comments. Currently, we can set this behavior by adding the condition We've taken note of this and will consider it for future change. I'm closing this issue for now. |
I have a related problem but this time with a nullable field. Hope it's ok to share a link to SO: https://stackoverflow.com/questions/70062891/cosmos-db-iqueryable-on-nullable-fields |
(already reported in v2, problem is still here in v3)
Describe the bug
LINQ queries with a condition on a non-nullable boolean property are not correctly translated to SQL. The translation doesn't account for the fact that the property could be undefined in the JSON document.
To Reproduce
Assuming an object model like this:
Make the following query:
Expected behavior
Documents where
IsDeleted
is not defined should be returned, because in the C# model the property is not nullable, so its absence really means that it's false.The generated SQL should be something like this:
Or maybe
Actual behavior
Documents where
IsDeleted
is not defined are not returned, becauseNOT (undefined)
doesn't evaluate to true.The generated SQL looks like this:
Environment summary
SDK Version: .NET Core 2.1, Microsoft.Azure.Cosmos 3.1.1
OS Version (e.g. Windows, Linux, MacOSX): Windows 10
The text was updated successfully, but these errors were encountered: