Projection middleware excluding getter-only properties — use anonymous types instead?
See original GitHub issueIs there an existing issue for this?
- I have searched the existing issues
Product
Hot Chocolate
Describe the bug
This problem, if fixed, would also basically resolve both #2365 and #2373; without virtually any substantial changes to Hot Chocolate.
There’s a library called EntityFrameworkCore.Projectables that basically adds the ability to declare computed properties on EF Core entity types:
using EntityFrameworkCore.Projectables;
public class Author
{
public required int Id { get; set; }
public required string FirstName { get; set; }
public required string LastName { get; set; }
[Projectable]
public string FullName => FirstName + " " + LastName;
}
All you need to do is define a getter-only property like above and you’re good to go (it will then replace every occurrence of that property in any expression passed to EF Core with its equivalent expression, which it gathers at compile-time with the help of source generators — you can read more about how it works on its README).
This means that you could now write something like this:
db.Authors.Select(a => new
{
a.FullName,
});
And it would be translated to the right SQL — as if you had used the expression a.FirstName + " " + a.LastName
directly inside the projection:
SELECT (a."FirstName" || ' ') || a."LastName" AS "FullName"
FROM "Authors" AS a
However, there is ONE thing that stops this from being the perfect solution to the computed property problem in Hot Chocolate+EF:
The problem is that the projection middleware refuses to include any getter-only properties in the projection expression that it generates. So, for example, if you execute the following query against the server:
{
author {
fullName
}
}
The expression it generates and passes to .Select
is the following:
_s1 => new Author() {}
It does not include the FullName
property in the projection that it sends to EF, and seems to then invoke the property on the application side afterwards.
It would’ve been perfect if it instead generated this:
_s1 => new { _s1.FullName }
Would it be possible to slightly modify the implementation of the projection middleware such that it uses anonymous objects instead, and also actually includes properties like this in the projection? Or at least provides an option that lets the developer enable this?
As I said in the beginning, this relatively minor adjustment to the projection middleware would effectively once and for all resolve age-old problems such as those described in #2365 and #2373, and any adjacent issues like #4995.
Could you please consider this? Tell me what you think. Thank you.
Steps to reproduce
Explained above.
Relevant log output
No response
Additional Context?
No response
Version
13.0.0
cc: @kresimirlesic
Issue Analytics
- State:
- Created 6 months ago
- Reactions:5
- Comments:37 (35 by maintainers)
Top GitHub Comments
I also don’t see it, and I’m wondering how it relates to #2575.
I think that it’s more powerful to allow anything to be projected, and to use the resolver to combine/construct the return value.
Maybe there could be an overload of
Resolve
that gives you the parent automatically?:@PascalSenn would you be able to rebase the projection engine PR branch onto master? It’s got to have come a long way in the last year, the reworking should probably be done against the latest version.