[CSHARP-1555] Projecting from and to the same type including the _id field causes deserialization to fail Created: 03/Feb/16 Updated: 04/Jul/22 Resolved: 04/Jul/22 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | Linq, LINQ3 |
| Affects Version/s: | 2.2 |
| Fix Version/s: | 2.17.0 |
| Type: | Bug | Priority: | Minor - P4 |
| Reporter: | Roberto Pérez | Assignee: | Robert Stam |
| Resolution: | Done | Votes: | 1 |
| Labels: | triaged | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||||||||||||||
| Epic Link: | CSHARP-3615 | ||||||||||||||||||||
| Backwards Compatibility: | Fully Compatible | ||||||||||||||||||||
| Description |
|
When using: yourMongoCollection.AsQueryable().Select(projectionExpression).ToList() in versions greater than 2.1.X it fails. The examples below just call Count() for demonstration purposes.
Execution output using .NEt Driver 2.1.1 or 2.1.0 1- Count 2- ToList Without Select 3.1- ToList With Select 3.2- ToList With Select 3.3- ToList With Select 3.4- ToList With Select Press any key to continue . . . Execution output using .NEt Driver 2.2.0 or greater 1- Count 2- ToList Without Select 3.1- ToList With Select 3.2- ToList With Select 3.3- ToList With Select 3.4- ToList With Select Press any key to continue . . . |
| Comments |
| Comment by James Kovacs [ 04/Jul/22 ] | ||||||||||||||||||||||
|
This issue has been fixed in the new LINQ provider (known as LINQ3), which was introduced 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
| ||||||||||||||||||||||
| Comment by Githook User [ 04/Jul/22 ] | ||||||||||||||||||||||
|
Author: {'name': 'Robert Stam', 'email': 'robert@robertstam.org', 'username': 'rstam'}Message: | ||||||||||||||||||||||
| Comment by Roberto Pérez [ 11/May/16 ] | ||||||||||||||||||||||
|
Hello Craig, After new attempts to workaround the problem we have found out more scenarios. Projecting from and to the same type including the _id field causes deserialization to fail: this is only true if you have not mark a property as Required
in any other case no matter which fields you select for your projection, it will not work if the same type is used for projection Regards | ||||||||||||||||||||||
| Comment by Craig Wilson [ 04/Apr/16 ] | ||||||||||||||||||||||
|
Understood. I'll keep thinking and hopefully come up with a better solution. This is just a very specific set of circumstances that I don't think many people will encounter. | ||||||||||||||||||||||
| Comment by Roberto Pérez [ 04/Apr/16 ] | ||||||||||||||||||||||
|
Hi Craig, First of all thank you very much for your work. In the examples shown here we noticed that anonymous classes elude the mentioned problem but as we were using the same type in projections with the Identifier in previous versions of the Driver we wouldn't like to change those pieces of code (the application is huge and we have built extension methods using generics to specify the projection in a layer on top of the Driver; so anonymous classes would not work for us and we would not like to create as many View classes as we would need in each scenario). We are still using .NET Driver version 2.1.1, anyway, if you come up with anything else, please tell us | ||||||||||||||||||||||
| Comment by Craig Wilson [ 04/Apr/16 ] | ||||||||||||||||||||||
|
One further note - This problem only manifest in the following conditions: 1) You are projecting to the same type. In the description example, both the original and the target type are the same. After further looking, this is a non-trivial fix. When you need to project an identifier, I'd suggest you use either anonymous types or create a new XXXView class to project into. | ||||||||||||||||||||||
| Comment by Craig Wilson [ 04/Apr/16 ] | ||||||||||||||||||||||
|
I have this down to a simple test we can add to MongoQueryableTests.cs.
I believe this issue is a couple of things rolled into one related to when to exclude projecting the _id field. We didn't have a test around this, so when some stuff changed, we didn't catch this change. Thanks for reporting. | ||||||||||||||||||||||
| Comment by Roberto Pérez [ 04/Feb/16 ] | ||||||||||||||||||||||
|
Hi Craig, Answering your questions: 2) The example of person was just to reproduce the error (this case is so simple that it is nonsense). I have comment the NoIdMemberConvention line but the result is the same:
Regards | ||||||||||||||||||||||
| Comment by Craig Wilson [ 04/Feb/16 ] | ||||||||||||||||||||||
|
In your examples, Person2 and the anonymous type also use a BsonClassMap, even though that part is hidden from you. In fact, in projections, we ignore any existing class maps for a number of reasons, but mostly due to compability with the instigating type. This is a guess, but since you have registered a NoIdMemberConvention, I imagine that this could be getting confused and not mapping the identifier properly. I'm not sure why the other forms work, so could you run a test and remove that from the conventions. I have 2 questions: Craig | ||||||||||||||||||||||
| Comment by Roberto Pérez [ 04/Feb/16 ] | ||||||||||||||||||||||
|
Hi Craig, The projection forces the error only when the class type used is one mapped in BsonClassMap.
Regards | ||||||||||||||||||||||
| Comment by Craig Wilson [ 03/Feb/16 ] | ||||||||||||||||||||||
|
Hi Roberto, I'll take a look and try and repro. This seems pretty straightforward, so I'm surprised it doesn't already work given that we have lots of users currently doing things exactly like this. Perhaps we are just missing a test? Craig |