2014-10-14 11 views
12

Używam Entity Framework 6.1, i mam kod jak poniżej:Dlaczego metoda Znajdź generuje zapytanie TOP (2)?

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); 
     } 
} 

A to generuje:

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 metoda zwraca pojedynczy wynik, ale to generuje TOP(2) zapytania zamiast 1. Czemu?

Uwaga: Jestem pewien, że przekazuję prawidłową Id metody i tak, Id jest kluczem podstawowym.

Odpowiedz

13

Jeśli spojrzeć na dokumentacji dla DbSet<TEntity>.Find Method:

Znajduje podmiot z podanych podstawowych wartości klucza.

Wziąłem okiem na kod źródłowy dla Find metody i stwierdził:

/// <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); 
    } 

więc metoda rzuci InvalidOperationException w przypadku wielu podmiotów.

Rzucony jeśli istnieje wiele podmiotów, w związku z podstawowych kluczowych wartościami podanymi

Wewnętrznie wywołanie Find nie przekłada się Single/SingleOrDefault; zamiast tego prosta pętla służy do sprawdzania wielu elementów.

Ponieważ metoda jest specyficzna dla klucza podstawowego, powinna generować wyjątek w przypadku wielu obiektów. Dlatego generuje zapytanie, aby wybrać co najmniej dwa rekordy. Podobny do wywołania Single.

+2

+1 dla źródła, zamiast spekulacji. –

9

Zgaduję pod kołdrą, która zostanie przekształcona w wywołanie Single lub coś, co wygląda na to. W takim przypadku LINQ chce mieć pewność, że jest tylko jeden wynik. Jeśli są zwrócone 2 rekordy, może wyrzucić.

Powiązane problemy