[CSHARP-3713] SelectMany doesn't support DefaultIfEmpty() Created: 17/Jun/21 Updated: 28/Oct/23 Resolved: 13/Oct/21 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | Linq, LINQ3 |
| Affects Version/s: | None |
| Fix Version/s: | 2.14.0 |
| Type: | Improvement | Priority: | Major - P3 |
| Reporter: | Björn Andersson | Assignee: | Robert Stam |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Description |
|
When unwinding lists using SelectMany, there is no way to force preserveNullAndEmptyArrays in the generated query. By adding DefaultIfEmpty() to the SelectMany as follows
it would be expected that an unwind with the preserveNullAndEmptyArrays option would be generated and empty lists that are unwinded would generate a copy of the parent object with a default object of the child. By simply changing MongoDB.Driver.Linq.Translators.QueryableTranslator.TranslateSelectMany line 340 from
to (i.e. remove the restriction to be a group join)
The desired result is achieved. However, this may cause unintended side-effects because I cannot understand why this support is not already there? |
| Comments |
| Comment by Björn Andersson [ 14/Oct/21 ] | ||||
|
Thank you! | ||||
| Comment by Robert Stam [ 13/Oct/21 ] | ||||
|
Note that we can only support `DefaultIfEmpty` when nested inside an aggregation expression. At the top level we don't know of any way to support `DefaultIfEmpty` because if the pipeline becomes empty before reaching this stage then the following stages don't even execute. | ||||
| Comment by Robert Stam [ 13/Oct/21 ] | ||||
|
This issue has been fixed in the new LINQ provider (known as LINQ3) which will be included in the upcoming 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 [ 13/Oct/21 ] | ||||
|
Author: {'name': 'rstam', 'email': 'robert@robertstam.org', 'username': 'rstam'}Message: | ||||
| Comment by Björn Andersson [ 29/Sep/21 ] | ||||
|
Hi! Do you have some kind of estimate around the new Linq implementation? I use a custom build of the driver right now which works, but it would be easier to update to new versions if I could use the official one Thanks! | ||||
| Comment by Dmitry Lukyanov (Inactive) [ 29/Jun/21 ] | ||||
|
Hey bjorn@livewrapped.com , this change looks reasonable but at the same time breaking. So we're going to postpone this until a new LINQ implementation which currently is being actively implemented/reviewed. We will let you know when it will be released. | ||||
| Comment by Björn Andersson [ 21/Jun/21 ] | ||||
|
Thank you very much! I'm aware of alternative solutions - I have working code that handle this, but I'm moving this code over to 100% linq since the code becomes a lot easier to read and easier to understand for non MongoDB experts. Everything is ported, this is the last part missing. I'm currently using a patched version of the driver, but I'd much rater user the official driver of course. I already made a PR with the changes I made (https://github.com/mongodb/mongo-csharp-driver/pull/553) but with my very limited knowledge of the driver's internals, I expect more work needs to be done (although I haven't really found anything while looking). Thanks again! | ||||
| Comment by Dmitry Lukyanov (Inactive) [ 21/Jun/21 ] | ||||
|
Hello bjorn@livewrapped.com , thanks for your report, we're able to reproduce this case and going to discuss it whether it's safe to change this behavior. We will let you know. Also, pay attention that you can reach the same behavior you request with this aggregation code:
|