2010-10-11 18 views
6

Mi proyecto (la capa UI es asp.mvc) se desarrolló utilizando .NET 3.5. Después de actualizar a .NET 4.0 Tengo un problema con las consultas compiladas:Problema de consulta compilada de DataContext con .NET 4

[ArgumentException: Query was compiled for a different mapping source than the one associated with the specified DataContext.] 
    System.Data.Linq.CompiledQuery.ExecuteQuery(DataContext context, Object[] args) +863348 
    System.Data.Linq.CompiledQuery.Invoke(TArg0 arg0, TArg1 arg1) +110 

Cada vez que tengo mi consulta estoy pasando mi contexto

return StaticQueries.getTopFiveOrders(mContext, int howMany); 


public static Func<Mycontext, int, IQueryable<Order>> getTopFiveOrders 
      = CompiledQuery.Compile 
       ((Mycontext mContext, int howMany) => 
       (some query).Distinct()); 

El error se produce en la segunda solicitud.

Respuesta

4

Esto se debe a un cambio en la forma en que operan las consultas compiladas.

Ahora deben ejecutarse siempre utilizando el mismo contexto.

This Microsoft connect page explica por qué se hizo el cambio:

El problema en este caso es causado por el hecho de que CompiledQuery requiere la misma fuente de mapas que se utilizará para todas las ejecuciones. En el ejemplo de código que está utilizando para reproducir el problema, las diferentes instancias de DataContext usan una nueva fuente de mapeo cada vez, pero la consulta no informa esto y simplemente falla silenciosamente. Si usa la propiedad DataContext.Log u otro registro como el Analizador de SQL Server, verá que el segundo UPDATE ni siquiera se está enviando al servidor.

Esto se ha corregido en .NET Framework 4.0, de modo que se informa una excepción que contendrá un mensaje como "Se compiló la consulta para una fuente de asignación diferente a la asociada con el DataContext especificado.", Y no lo hará solo silenciosamente fallan Sin embargo, el código que proporcionó y que está funcionando es la forma correcta de hacerlo, porque usa el mismo origen de mapeo estático para todas las instancias de LinqTestDataContext.

Básicamente siempre era un problema, pero utiliza a fallar en silencio, que acaba de hacer el fracaso explícito en .NET 4.

0

también me enfrenté al problema similar. Eliminé la estática de las consultas compiladas, funciona bien. Aunque todavía tengo que descubrir cuánta diferencia hace en el rendimiento.

1

Pasé una buena cantidad de tiempo mirando esto y cómo se ha cambiado el comportamiento en .NET 4.0. He detallado mis hallazgos con más detalle en mi blog aquí:

http://www.roushtech.net/2014/01/19/statically-compiled-linq-queries-broken-in-net-4-0/

bruto de ella es: Microsoft hizo un cambio de proteger a la gente de hacer algo tonto (Reutilizando una consulta compilada entre las diferentes asignaciones), pero parece haber roto un importante beneficio de rendimiento (reutilización de una consulta compilada entre diferentes contextos del MISMO MAPEO, pero diferentes instancias del mapeo).

El uso de captadores, o CompiledQuery que es miembro de su clase, solo dará como resultado una recompilación constante y ningún beneficio de rendimiento real.