FirstOrDefaultAsync() & SingleOrDefaultAsync() vs FindAsync() EFCore : <p>We have 3 different approaches to get  single items from EFCore they are <code>FirstOrDefaultAsync()</code>, <code>SingleOrDefaultAsync()</code> (including its versions with not default value returned, also we have <code>FindAsync()</code> and maybe more with the same purpose like <code>LastOrDefaultAsync()</code>. </p>

<pre><code>     var findItem = await dbContext.TodoItems
       .FindAsync(request.Id)
       .ConfigureAwait(false);

     var firstItem = await dbContext.TodoItems
        .FirstOrDefaultAsync(i =&gt; i.Id == request.Id)
        .ConfigureAwait(false);

     var singleItem = await dbContext.TodoItems
        .SingleOrDefaultAsync(i =&gt; i.Id == request.Id)
        .ConfigureAwait(false);
</code></pre>

<p>I would like to know the differences between each one of them. So far what I know is that we <code>FirstOrDefaultAsync()</code> to get the first given a condition, (usually using this because we know that more than one item can satisfy the condition), on the other hand we use  <code>SingleOrDefaultAsync()</code> because we know that there is only one possible match to find, and <code>FindAsync()</code> to get an item given its primary key.</p>

<p>I think <code>FirstOrDefaultAsync()</code> &amp; <code>SingleOrDefaultAsync()</code> always hit the database (not sure about this), and <code>FindAsync()</code> this is what Microsoft docs says:</p>

<blockquote>
  <p>Asynchronously finds an entity with the given primary key values. If
  an entity with the given primary key values exists in the context,
  then it is returned immediately without making a request to the store.
  Otherwise, a request is made to the store for an entity with the given
  primary key values and this entity, if found, is attached to the
  context and returned. If no entity is found in the context or the
  store, then null is returned.</p>
</blockquote>

<p>So my question is, if our given condition used for <code>FirstOrDefault()</code>, <code>SingleOrDefault()</code> and <code>FindAsync()</code> is the primary key, <strong>do we have any actual difference?</strong></p>

<p>What I think is that the first time they are used always hit the db, <strong>but what about the next calls?</strong>. And probably EFCore could use the same context to get the values for <code>FirstOrDefault()</code> and <code>SingleOrDefault()</code> as it does for <code>FindAsync()</code>, <strong>maybe?</strong>.</p>
