question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Projection middleware excluding getter-only properties — use anonymous types instead?

See original GitHub issue

Is 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:

image

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:open
  • Created 6 months ago
  • Reactions:5
  • Comments:37 (35 by maintainers)

github_iconTop GitHub Comments

1reaction
glen-84commented, Apr 14, 2023

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.

descriptor
    .Field("fullName")
    .Projects(u => new { u.FirstName, u.LastName })
    .Resolve(ctx => ctx.Parent<User>().FirstName + " " + ctx.Parent<User>().LastName);

Maybe there could be an overload of Resolve that gives you the parent automatically?:

descriptor
    .Field("fullName")
    .Projects(u => new { u.FirstName, u.LastName })
    .Resolve(u => $"{u.FirstName} {u.LastName}");
0reactions
AntonC9018commented, May 15, 2023

@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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Overfetching problem when querying related entities and ...
aradalvand mentioned this issue on Mar 29. Projection middleware excluding getter-only properties — use anonymous types instead? #6002.
Read more >
Adding computed fields (Entity Framework) · Issue #2365
I'm intending to use Hot Chocolate with Entity Framework, ... Projection middleware excluding getter-only properties — use anonymous types ...
Read more >
c# - Non-read only alternative to anonymous types
A member needs to be a property instead of a field if a class or (possibly-future) derivative might want non-default behavior, but since ......
Read more >
books-library.net-10251926Tl5A6.pdf
Unfortunately, C# doesn't allow anonymous types to escape method scope; instead, you can return it as a weakly typed object, and then use...
Read more >
UDN Search
permitted parents any element that accepts flow content implicit aria role table permitted aria roles any dom interface htmltableelement attributes this ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found