[CSHARP-4066] Only use regex filters against string properties that are serialized as strings Created: 19/Feb/22 Updated: 28/Oct/23 Resolved: 24/Mar/22 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | LINQ3 |
| Affects Version/s: | 2.14.1 |
| Fix Version/s: | 2.15.0 |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Felix König | Assignee: | Robert Stam |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||
| Epic Link: | CSHARP-3615 | ||||||||
| Backwards Compatibility: | Fully Compatible | ||||||||
| Description |
|
I have a struct that has an "Id" field mapped using a custom serializer. Unfortunately LINQ queries, in my example Find, does not seem to use the serializer, causing the query to not match any documents. here is a full test case that reproduces the issue:
|
| Comments |
| Comment by Felix König [ 24/Mar/22 ] | ||||||||||||||||||||||
|
Thank you very much, now everything seems to work as expected. All my tests passed 😁 | ||||||||||||||||||||||
| Comment by Robert Stam [ 24/Mar/22 ] | ||||||||||||||||||||||
|
Thank you for following up. You are correct that your original repro still exhibits the problem and having investigated it I understand why and what you could change to make it work. The root of the problem is that in general we have no way of knowing what a custom serializer will do. So for the most part we assume that a `string` property will actually be serialized as a `string`. Your custom serializer doesn't do that, but we don't know that. You easiest fix would probably be to just use the standard `StringSerializer` but customize it to convert `strings` to `ObjectIds` when serializing them. The easiest way to do that is to annotate the field like this:
If you want to use a custom serializer you can do that, but you need to help the driver out a bit by letting it know that your custom serializer does not in fact serialize a `string` as a `string`. The way to do that is for your serializer to implement the `IRepresentationConfigurable` interface. The driver will detect that your custom serializer implements this interface and can then use it to interrogate whether your custom serializer serializes `strings` as `strings` or not. To implement this interface implement the following property and method:
Since your custom serializer does not support configuring the representation simply throw `NotSupportedException` if `WithRepresentation` is called. The key here is that the `Representation` property returns `BsonType.ObjectId` (NOT `BsonType.String`) which informs the driver that this `string` is not actually serialized as a `string`.
| ||||||||||||||||||||||
| Comment by Felix König [ 24/Mar/22 ] | ||||||||||||||||||||||
|
Thank you for taking a look. I see the issue is marked as Fixed for version 2.15.0. However, I can still reproduce the test failure using my original reproduction. Could you double-check whether the issue is actually fixed in version 2.15.0? | ||||||||||||||||||||||
| Comment by Githook User [ 02/Mar/22 ] | ||||||||||||||||||||||
|
Author: {'name': 'rstam', 'email': 'robert@robertstam.org', 'username': 'rstam'}Message: | ||||||||||||||||||||||
| Comment by James Kovacs [ 23/Feb/22 ] | ||||||||||||||||||||||
|
Simplified repro:
With LINQ3, the output is:
This is incorrect as the database type is BsonType.ObjectId, but the comparison is being performed against BsonType.String. With LINQ2, we compare using the correct database type:
| ||||||||||||||||||||||
| Comment by James Kovacs [ 23/Feb/22 ] | ||||||||||||||||||||||
|
Hi, de.felix.koenig@gmail.com, Thank you for reporting this issue. We have confirmed that your repro demonstrates the problem in LINQ3. LINQ3's ComparisonExpressionToFilterTranslator has short-circuit logic to render string comparisons (line 66) and we never reach line 79 where we render the MQL with the configured serializer. This results in rendering the comparison as "_id": "590df61373b975210006fcdf" rather than "_id": ObjectId("590df61373b975210006fcdf"). Since a string is not the same type as an ObjectId, no documents match. Please follow this ticket for updates as we work to resolve this issue. Sincerely, | ||||||||||||||||||||||
| Comment by Esha Bhargava [ 22/Feb/22 ] | ||||||||||||||||||||||
|
de.felix.koenig@gmail.com Thank you for reporting this issue! We'll look into it and get back to you soon. |