Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Find method generates a TOP(2) query?

I'm using Entity Framework 6.1, and I have a code like this:

Brand b;
using(var ctx = new KokosEntities())
{
      try
      {  
          b = ctx.Brands.Find(_brands[brandName].Id);
          return b;
      }
      catch (Exception ex)
      {
           _logger.Log(LogLevel.Error, ex);
      }
 }

And this generates:

 N'SELECT TOP (2) 
[Extent1].[Id] AS [Id], 
[Extent1].[Name] AS [Name], 
[Extent1].[OpenCartId] AS [OpenCartId]
FROM [dbo].[Brands] AS [Extent1]
WHERE [Extent1].[Id] = @p0',N'@p0 int'

Find method returns a single result but it generates a TOP(2) query instead of 1. Why?

Note: I'm sure I'm passing correct Id to the method, and yes, Id is the primary key.

like image 531
Selman Genç Avatar asked Oct 14 '14 16:10

Selman Genç


1 Answers

If you look at the documentation for DbSet<TEntity>.Find Method:

Finds an entity with the given primary key values.

I took a peek at the source code for Find method and found:

/// <exception cref="T:System.InvalidOperationException">Thrown if multiple entities exist in the context with the primary key values given.</exception><exception cref="T:System.InvalidOperationException">Thrown if the type of entity is not part of the data model for this context.</exception><exception cref="T:System.InvalidOperationException">Thrown if the types of the key values do not match the types of the key values for the entity type to be found.</exception><exception cref="T:System.InvalidOperationException">Thrown if the context has been disposed.</exception>
    public virtual TEntity Find(params object[] keyValues)
    {
      return this.GetInternalSetWithCheck("Find").Find(keyValues);
    }

so the method will throw InvalidOperationException in case of multiple entities.

Thrown if multiple entities exist in the context with the primary key values given

Internally the call to Find doesn't translate into Single/SingleOrDefault; instead a simple loop is used to check for multiple entities.

Since the method is specific to the primary key, it should throw an exception in case of multiple entities. That is why it is generating a query to select at least two records. Similar to Single call.

like image 97
Habib Avatar answered Oct 12 '22 12:10

Habib