[CSHARP-4586] Projections not retrieving expected fields after upgrading to 2.19 driver Created: 28/Mar/23  Updated: 28/Oct/23  Resolved: 05/Apr/23

Status: Closed
Project: C# Driver
Component/s: LINQ3
Affects Version/s: None
Fix Version/s: 2.19.2

Type: Bug Priority: Major - P3
Reporter: Paul Spangler Assignee: Robert Stam
Resolution: Fixed Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Zip Archive ConsoleApp1.zip    
Issue Links:
Related
is related to CSHARP-4591 AutoMap constructors for mutable clas... Backlog
Documentation Changes: Not Needed
Documentation Changes Summary:

1. What would you like to communicate to the user about this feature?
2. Would you like the user to see examples of the syntax and/or executable code and its output?
3. Which versions of the driver/connector does this apply to?


 Description   

Summary

After upgrading to the 2.19 (and 2.19.1) driver with the LINQ3 provider enabled by default, our expression-based projections are no longer retrieving all of the expected fields. Tested against a standalone 5.0.15 server.

How to Reproduce

ConsoleApp1.zip

The attached example includes the connection string and name of the database as arguments in the launchSettings.json. The relevant part is:

var filter = Builders<Model>.Filter.Eq(m => m.Id, modelToInsert.Id);
var foundProjection = await collection.Find(filter)
    .Project(Builders<Model>.Projection.Expression(
        m => new View(m.Id) { }))
    .SingleAsync();

Specifically, having both constructor parameters and initializer braces (whether we actually assign to any properties or not) prevents the driver from retrieving the fields being passed to the constructor. In this case, the result is that the retrieved object has a null ID property even though we requested the ID field via the expression. Removing the {} after "new View(m.Id)" avoids the issue (though in real code we are retrieving additional properties). Removing the Version property from the View class such that all properties are set via constructor also avoids the issue.

Additional Background

We ran into this issue after upgrading to the 2.19 driver, presumably because of the switch to the LINQ3 provider by default. Manually switching back to the LINQ2 provider avoids the issue.



 Comments   
Comment by Githook User [ 18/May/23 ]

Author:

{'name': 'rstam', 'email': 'robert@robertstam.org', 'username': 'rstam'}

Message: CSHARP-4586: Map constructor in MemberInit and simplify $project for simple field inclusion.
Branch: v2.19.x
https://github.com/mongodb/mongo-csharp-driver/commit/164667d95eca43972c0a94b4cf4bda3bd2dae197

Comment by Githook User [ 05/Apr/23 ]

Author:

{'name': 'rstam', 'email': 'robert@robertstam.org', 'username': 'rstam'}

Message: CSHARP-4586: Map constructor in MemberInit and simplify $project for simple field inclusion.
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/d0405409e121b7171027713bb15d31db4eafede1

Comment by Robert Stam [ 30/Mar/23 ]

One of the factors at play in this issue is that the View class was not automapped as expected because of the `init` property.

I've worked around this in the LINQ code, but as a result of this investigation I've opened CSHARP-4591 to investigate whether we should always automap constructors.

Comment by Robert Stam [ 30/Mar/23 ]

Thanks for providing a high quality sample reproduction.

I have a fix in code review. 

Comment by Robert Stam [ 28/Mar/23 ]

Thanks for reporting this issue. I will look into it.

Generated at Wed Feb 07 21:48:41 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.