-
Notifications
You must be signed in to change notification settings - Fork 2k
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
First() vs Single() for queries that return one result #4835
Comments
I'm planning some work on our query documentation, I'll make a note to possibly integrate some guidance there. There's no completely clear-cut answer: you're right that limiting to 2 results instead of 1 could have a perf impact on some queries; on the other hand, First() requires an ordering to work reliably (EF warns when there isn't one), whereas Single() does not... And Single() can more clearly express the intent of a given query. |
@roji what about the case when doing a First\FirstOrDefault for cases when I'm selecting by a unique id column..
|
@KLuuKer I don't think there's anything to say beyond what I already wrote above; I'd generally recommend just using SingleOrDefaultAsync, as that makes it very clear to the reader that you're not getting the first row out of several, but are rather asserting that there's only one (or zero) possible rows. The only downside is the In theory, EF could know the the query can only ever return a single row (because it knows UserId is unique), and flow that information, affecting the translation of FirstOrDefaultAsync/SingleOrDefaultAsync. But that sort of optimization is a bit far off. |
@roji I'm more annoyed by the warning i get in my logs (of not including an order by), |
@KLuuKer that's why I'm suggesting using SingleOrDefaultAsync. |
@roji but i don't want |
Why don't you want |
@KLuuKer I think the example in your comment will not generate a FirstWithoutOrderByAndFilterWarning. This warning is generated when the query does not contain a predicate (filter) or an ordering. But your query does contain a predicate Here is the relevant piece of code that shows when this warning is generated for relational databases. If the query contains either a predicate (filter) or an ordering, the warning is Not generated. |
@roji
so might it be because of the split query mode? (we have AsSplitQuery enabled by default) p.s. happy new year 🎉 |
@KLuuKer I don't see what any of that is relevant to wanting or not wanting |
I think the Entity Framework documentation should recommend one option over the other when the user knows that the query will return one result.
I think the feature of Single() throwing an exception when there is more than one matching element is rarely needed when querying a database because users are normally querying to fetch data, not to validate data already saved in the database.
Single() should have a worse performance in at least some cases since it may require a full table scan to ensure there isn't a second match.
This ASP.NET article recommends First() over Single()
https://learn.microsoft.com/en-us/aspnet/core/data/ef-rp/crud?view=aspnetcore-8.0#ways-to-read-one-entity
But I saw @roji recommending Single() over First() in some issue comments
dotnet/efcore#31623 (comment)
dotnet/efcore#29782 (comment)
Also using First() without OrderBy() produces a warning
Which makes me think the Entity Framework team wants users to call Single() for queries that return one item.
It will also help if the documentation says when First() performs significantly better that Single(). For example when filtering by a non-indexed column.
The text was updated successfully, but these errors were encountered: