Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Higher-level API over ExecuteUpdate for variable property sets #29654

Open
roji opened this issue Nov 22, 2022 · 3 comments
Open

Higher-level API over ExecuteUpdate for variable property sets #29654

roji opened this issue Nov 22, 2022 · 3 comments

Comments

@roji
Copy link
Member

roji commented Nov 22, 2022

Traditionally, updating an entity in a disconnected application requires the client to submit the entire entity (all properties); the server must then reload the entity again, just in order to perform change tracking and compute which properties changed. In addition to this extra database roundtrip and traffic, the client needlessly sends all properties of the entity, as opposed to only those which changed.

To make this more efficient, the client can itself compute the change properties, and send a "patch" message to the application with only the properties that changed (e.g. via an HTTP PATCH verb). The application can then directly persist those changes.

EF Core 7.0 introduced ExecuteUpdate, which is ideal exactly for performing a precise update without involving change tracking. However, ExecuteUpdate requires spelling out the properties to be set:

await context.Posts
    .ExecuteUpdateAsync(s => s
        .SetProperty(b => b.Title, b => b.Title + " (" + b.PublishedOn.Year + ")")
        .SetProperty(b => b.Content, b => b.Content + " ( This content was published in " + b.PublishedOn.Year + ")"));

But typically, the set of properties may vary across requests (because users change different sets of properties). Doing this with ExecuteUpdate is unwieldy, since it requires dynamic construction of the expression tree. We could add a higher-level API above ExecuteUpdate, which allows specifying the properties in an easier way.

In addition, in some cases users may wish to update all properties, effectively replacing an existing entity (e.g. HTTP PUT). Rather than requiring the user to spell out all the properties, this higher-level API could include that functionality as well.

Note that this variable property sets presents a particular difficulty for AOT (and also for perf in general)... Since different property setters mean a different expression tree, each set would require a full compilation via the query pipeline (which we ideally want to trim away in AOT mode). Even without AOT, compilation imposes an overhead which hurts perf. We could consider disregarding the property setters for the purposes of (1st-level) query caching, etc.

/cc @davidfowl @DamianEdwards

@roji
Copy link
Member Author

roji commented Jan 4, 2024

Note #32018 which goes in this direction. If we do this well, it may be sufficient as a way of constructing dynamic ExecuteUpdates.

@johnkwaters

This comment was marked as off-topic.

@roji

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants