EntityFrameworkCore.Projectables icon indicating copy to clipboard operation
EntityFrameworkCore.Projectables copied to clipboard

allow properties to have a setter. closes #77

Open hahn-kev opened this issue 2 years ago • 8 comments

This adds support for properties to have a getter (and setter), closes #77. Like this:

public int Prop {
    get => Field;
}

I was able to run a generator test and verify this works, however I kept getting a compile error from the generator on the same code for the functional tests. I'm not sure how to fix that one.

hahn-kev avatar Aug 15 '23 10:08 hahn-kev

It looks like the tests failed because some properties are getting selected automatically when there's no select statement. Since these properties can have a setter they will get automatically selected by EF when there's no select. For example DbSet.Where(u => u.Name = "test).ToList() there's no select here, so EF will select any writable property, this means that the select doesn't get processed by our code and so it selects properties that are actually aliases. I wonder if there's a way that we can tell EF to skip those properties.

hahn-kev avatar Aug 16 '23 05:08 hahn-kev

I wonder if we can somehow not map any properties with Projectable, for read only properties it's not needed, but for writable properties they need to be marked as Not mapped or ignored by EF.

hahn-kev avatar Aug 17 '23 07:08 hahn-kev

I wonder if there's a way that we can tell EF to skip those properties.

I would say we want to select these but based on the projectable expression. I would expect Alias to be computed for me if I queried an Entity without an explicit select clause.

koenbeuk avatar Aug 18 '23 01:08 koenbeuk

We would essentially want to translate:

dbContext.Entity into dbContext.Entity.Select(x => new Entity { Id = x.Id, Alias = x.Alias })

This is not a trivial undertaking. If you want to give it a shot then the translation could be performed in EntityFrameworkCore.Projectables.Services.ProjectableExpressionReplacer by adding and implementing this:

        protected override Expression VisitExtension(Expression node)
        {
            if (node is QueryRootExpression)
            {
                throw new NotImplementedException("Do some magic here to reference projectable properties");
            }

            return node;
        }
``

koenbeuk avatar Aug 18 '23 01:08 koenbeuk

#84 Is another example of an expression that could be closed if we were to rewrite QueryRootExpressions

koenbeuk avatar Sep 10 '23 14:09 koenbeuk

If I understood correctly, QueryRootExpression is the initial dbset so dbContext.Entity for your example. If we were to rewrite the root, would all others rewritter become useless, since projectable fields would become available from the new Select clause?

zoriya avatar Sep 23 '23 10:09 zoriya

@zoriya No, this would only make it so that all projectable members of the source type will be expanded. A user can still apply additional Select expressions which will essentially cause the rewrite to become a no-op.

koenbeuk avatar Sep 24 '23 23:09 koenbeuk

I'd be happy if someone wants to take that on, but I don't have time to do that part right now.

hahn-kev avatar Sep 25 '23 01:09 hahn-kev