[CSHARP-921] Any subquery fails for Nullable<ObjectId> comparison Created: 05/Mar/14 Updated: 23/Jun/15 Resolved: 05/Mar/14 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | None |
| Affects Version/s: | 1.8.3 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Michael Kennedy | Assignee: | Unassigned |
| Resolution: | Won't Fix | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Attachments: |
|
| Backwards Compatibility: | Fully Compatible |
| Description |
|
Take these queries and try to run them. You will get the following exception: ObjectId?[] supplierIds = var supplierProducts = Unhandled Exception: System.NotSupportedException: Unable to determine the serialization information for the expression: Nullable<ObjectId>[]: { 000000000000000000000016, 000000000000000000000019, 000000000000000000000002, 000000000000000000000003 }. An alternate attempt at that query with ObjectId[] rather than ObjectId[] gives basically the same failure: ObjectId[] supplierIds = var supplierProducts = However, if I use Contains rather than Any, it works! But it is more painful because I need to convert to an nullable ObjectId array when the source is not actually nullable (required so supplierIds.Contains() compiles): ObjectId?[] supplierIds = var supplierProducts = I've attached the two related classes involved in the query. |
| Comments |
| Comment by Michael Kennedy [ 05/Mar/14 ] |
|
Make sense. It's slightly more painful to write the contains because of the type mismatch but that's somewhat a weakness of C# not being able to answer does a nullable value type live in a non-nullable typed array. Thanks for the feedback. |
| Comment by Craig Wilson [ 05/Mar/14 ] |
|
Interesting use case. I'm inclined to mark this as won't fix unless I'm missing something. What gets translated when using Contains on a local "array" is an $in clause is generated. {x: { $in : [1,2,3]}}. The problem with supporting Any in this fashion is that there is only 1 version of Any that would actually be legitimate (and it happens to be the one you are using). It takes the form of localArray.Any(item => item == value). If any other type of comparison is used inside the Any predicate, it no longer has a valid translation to MongoDB query syntax (or at least an efficient one). As such, using Contains on the local "array" is the supported form for this type of query. Thoughts? |
| Comment by Michael Kennedy [ 05/Mar/14 ] |
|
I should probably have entitled this IQueryable<T>.Any subquery fails for ObjectId[] comparison. I originally wanted to use ObjectId[] but had to move to ObjectId?[] to use Contains (which is effectively the same but works). |