[CSHARP-3696] Linq, Polimorphism, Downcast, OfType delivers wrong type Created: 01/Jun/21 Updated: 27/Oct/23 Resolved: 02/Jun/21 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | Linq |
| Affects Version/s: | 2.12.2, 2.12.3 |
| Fix Version/s: | None |
| Type: | Task | Priority: | Unknown |
| Reporter: | Thomas M | Assignee: | James Kovacs |
| Resolution: | Works as Designed | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Environment: |
Windows 10, Visual Studio 2019 |
||
| Attachments: |
|
| Description |
|
Hello I have insert a Record of Type AlotOfDataEntry wich Inherited LessDataEntry. If i try to get LessDataEntry from the collection, all Data of AlotOfDataEntry will be loaded. It should only load the Data from LessDataEntry. ^^
|
| Comments |
| Comment by James Kovacs [ 02/Jun/21 ] | |||||||||
|
Hi, Thomas, Thank you for your additional question. There is not a generic mechanism to project into a new object as it is highly dependent on your application models. You could write your own implementation of ToType<TTo>() that would match properties by property name or match property names to constructor arguments. This could be done as an extension method on IMongoQueryable<TFrom>, but would involve a lot of tricky reflection code to build up an expression, which could then be passed to LINQ's Select to perform the transformation. It is probably going to be easier to write concrete transformations on a case by case basis. Sincerely, | |||||||||
| Comment by Thomas M [ 02/Jun/21 ] | |||||||||
|
Hi James, thx for your Answer. Is there a generic way for the Select (project) with the new Object? Or will be there a way to do this generic in the future? like:
greetings Thomas | |||||||||
| Comment by James Kovacs [ 01/Jun/21 ] | |||||||||
|
Hi, Thomas, Thank you for reaching out to us with your .NET/C# driver question. We understand that your data model contains documents with large infrequently used fields. You are attempting to use polymorphism to only load a portion of the data, but are noticing that all data is loaded even when you query via the base class. This is behaviour works as designed. Polymorphism in the .NET/C# driver isn't intended as a mechanism to reduce the amount of data loaded. It is a way to query and store related models in a generic way. The ability to treat cars, boats, and planes as a vehicle rather than worrying about their individual types. Even when you load a vehicle document into an object, the underlying type is still a car (or boat or plane). When you use OfType, this is akin to a filter. Let's say you have a collection of type Vehicle. You can use OfType<Car>() to filter out and only retrieve documents of type Car. The resulting Car documents still have all the fields that you would expect for a car. You just happened to query them from the Vehicle collection. What you are attempting to do is only fetch a portion of the data present in a document. This is accomplished via projection in MongoDB. You can project into a known type such as LessDataEntry or an anonymous type depending on your needs. If you are using LINQ, the Select method is synonymous with project.
Executing ToString() on a query renders to its JSON equivalent. (The query is actually serialized to BSON or binary JSON to be sent to the server, but JSON is more human readable.) Note how only the _id and Name fields are retrieved from the server.
If you had specified a filter (aka where clause), the query would have included an initial $match stage to filter down the results. Sorting the results would have appended a $sort stage. In summary, if you want to limit the amount of data retrieved from your cluster to avoid returning large, unused fields, use a projection in your query. Please let us know if you have any additional questions. Sincerely, |