Closed bradtglass closed 1 year ago
This is by-design. Regardless of the GroupBy or anything else going on in the query, EF does not translate constructor calls inside queries. This is because constructors are functions which could contain arbitrary logic which EF cannot know about; EF doesn't translate arbitrary function calls either for the same reason.
EF does translate instantiations which use initializers (e.g. new Blog { Name = x }
), since you're clearly specifying which properties should get assigned which values. That's a compromise to allow people to project out their own types.
Note that I came across a bit of oddness in EF's policy here, opened #31315 to track.
Thanks @roji that makes sense, it feels like a limitation but I can understand why we wouldn't want to run the risk of side effects from the constructor call
Description
There some sample code below which explain the issue better than me but basically if you do a
GroupBy()
then aSelect()
then aWhere()
then there are some cases where this order works and some where it doesn't. Usually I would just put the select after theWhere()
to fix this but we have some examples where we're selecting aggregate values which are needed in theWhere()
.Basically this works when the
Select()
is creating a new object by property initialisation syntax but not when using constructor initialisation. I can understand why logically this is easier, we're setting a property and then using it's value so we can track which value that was.If constructor initialisation was supported in this scenario I would expect it to use property conventions similar to those that EF core uses for entity classes (if the name and type of the constructor parameter is the same but lower case of a property then match them up). This is a scenario that comes up a lot where we use the
Select()
to project our query into arecord
type which will usually only have a constructor.Example
This example is the simplest I could make to replicate the Exception. It shows the same query projecting into a simple POCO
class
and arecord
, the first query executes fine, the second throws an Exception (details at the bottom).I tested this sample using EF Core 7 and the preview of EF Core 8 and got the same result in both. Also worth pointing out that this is with SQL Server, I assume this will be different in other providers.
The second query produces the following exception details: