tutorial net mvc framework first español compact code asp entity-framework ef-code-first dbcontext sql-server-ce-4 dbset

entity framework - net - DbSet.Find método ridículamente lento en comparación con.SingleOrDefault en ID



mvc entity framework español (1)

Tengo el siguiente código (la base de datos es SQL Server Compact 4.0):

Dim competitor=context.Competitors.Find(id)

Cuando perfilo esto, el método Find tarda más de 300 ms para recuperar al competidor de una tabla de solo 60 registros.

Cuando cambio el código a:

Dim competitor=context.Competitors.SingleOrDefault(function(c) c.ID=id)

Entonces el competidor se encuentra en solo 3 ms.

La clase Competidor:

Public Class Competitor Implements IEquatable(Of Competitor) Public Sub New() CompetitionSubscriptions = New List(Of CompetitionSubscription) OpponentMeetings = New List(Of Meeting) GUID = GUID.NewGuid End Sub Public Sub New(name As String) Me.New() Me.Name = name End Sub ''ID'' Public Property ID As Long Public Property GUID As Guid ''NATIVE PROPERTIES'' Public Property Name As String ''NAVIGATION PROPERTIES'' Public Overridable Property CompetitionSubscriptions As ICollection(Of CompetitionSubscription) Public Overridable Property OpponentMeetings As ICollection(Of Meeting) End Class

Definí las relaciones de muchos a muchos para CompetitionSubscriptions y OpponentMeetings usando la API fluida.

La propiedad de ID de la clase Competitor es una Longitud que se traduce por Código primero en una columna de Identidad con una clave principal en la tabla de datos (SQL Server Compact 4.0)

¿¿Que esta pasando aqui??


Find llamadas DetectChanges internamente, SingleOrDefault (o, en general, cualquier consulta) no lo hace. DetectChanges es una operación costosa, por lo que Find es más lento (pero puede volverse más rápido si la entidad ya está cargada en el contexto porque Find no ejecutará una consulta sino que solo devolverá la entidad cargada).

Si desea utilizar Find para muchas entidades, por ejemplo en un bucle, puede desactivar la detección automática de cambios de esa manera (no se puede escribir en VB, por lo tanto, un ejemplo de C #):

try { context.Configuration.AutoDetectChangesEnabled = false; foreach (var id in someIdCollection) { var competitor = context.Competitors.Find(id); // ... } } finally { context.Configuration.AutoDetectChangesEnabled = true; }

Ahora, Find no llamará a DetectChanges con cada llamada y debería ser tan rápido como SingleOrDefault (y más rápido si la entidad ya está conectada al contexto).

La detección automática de cambios es un tema complejo y algo misterioso. Una gran discusión detallada se puede encontrar en esta serie de cuatro partes:

(Enlace a la parte 1, los enlaces a las partes 2, 3 y 4 están al principio de ese artículo)

http://blog.oneunicorn.com/2012/03/10/secrets-of-detectchanges-part-1-what-does-detectchanges-do/