-
Notifications
You must be signed in to change notification settings - Fork 3.8k
.Net: Change UpsertAsync return type to IReadOnlyList<TKey> #11402
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
.Net: Change UpsertAsync return type to IReadOnlyList<TKey> #11402
Conversation
@roji are you sure that we should return |
I'm honestly not completely sure. From our last design discussion on this, I got the impression that @westey-m and @dmytrostruk felt strongly that this is something we should keep. I'm on the fence - it is a capability that's shared across at least our relational providers (PG, SQL Server, SQLite), and I think @westey-m said at least one other non-relational database supports it (we should confirm, though even if not, that might not be a sufficient reason not to support it). I do think that once we remove the IAsyncEnumerable in this PR, there's much less objection to supporting this - it no longer really gets in the way, since users can just ignore the return value. So I think there's at least consensus that this is the minimum we want to do. But I'm totally fine with discussing this again and seeing how we feel about removing the feature altogether. It would be good to have the definitive list of database which do support this, though. |
My understanding was that we do the research first to find out whether any non-relational DB supports it. If not, we make it return |
OK, no problem - let's wait with this PR then until the research is done and we rediscuss (@westey-m I think this one's on you - I'll assign the issue back to you). I'll turn this into a draft in the meantime. |
@westey-m @adamsitnik I've rebased this PR and updated the docs to make it extra clear that batching UpsertAsync isn't idempotent when store-generated keys are in use, and atomicity isn't guaranteed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you @roji !
{ | ||
yield return (TKey)keyProperty.GetValueAsObject(record!)!; | ||
} | ||
return records.Select(r => (TKey)keyProperty.GetValueAsObject(r!)!).ToList(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the bang still required?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The one on r
isn't (because we now have a notnull
constraint on TRecord), the other unfortunately still is... We need to replace at least some of the calls to GetValueAsObject (and Set) with generic getters/setters - that would allow #11183, but would also obviate the bang (since TKey is constrained to notnull
. Later :)
@@ -47,11 +47,7 @@ public override async Task InitializeAsync() | |||
|
|||
protected virtual async Task SeedAsync() | |||
{ | |||
// TODO: UpsertBatchAsync returns IAsyncEnumerable<TKey> (to support server-generated keys?), but this makes it quite hard to use: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks much better now 💯
I actually now seem to remember that a .NET design guideline is to not return collection interfaces, but rather prefer concrete types (so |
Note: this PR is based on top of #11392, review 2nd commit onlyCloses #10692