Higher-level API over ExecuteUpdate for variable property sets
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
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:
```c#
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
Contributor guide
Assessment
This issue has not been assessed yet.