2010-10-11 12 views
6

Mój projekt (warstwa interfejsu użytkownika to asp.mvc) został opracowany przy użyciu .NET 3.5. Po uaktualnieniu do .NET 4.0 Mam problem z opracowanych zapytaniami:DataContext skompilował problem zapytania z .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 

Za każdym razem, gdy uruchomię mojej kwerendy jestem przechodzącej mój kontekst

return StaticQueries.getTopFiveOrders(mContext, int howMany); 


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

Błąd występuje na drugim wniosku.

Odpowiedz

4

Jest to spowodowane zmianą sposobu działania zapytań kompilowanych.

Teraz muszą być zawsze uruchamiane w tym samym kontekście.

This Microsoft connect page wyjaśnia, dlaczego zmiana została wprowadzona:

Problemem w tym przypadku jest spowodowane faktem, że CompiledQuery wymaga tego samego źródła mapowania być używany do wszystkich egzekucji. W kodzie przykład używamy do odtworzenia problemu, różnych instancji DataContext za pomocą nowego źródła mapowania za każdym razem, ale zapytanie nie zgłasza tego i po prostu cicho zawiedzie. Jeśli użyjesz właściwości DataContext.Log lub innego rejestrowania, takiego jak program SQL Server Profiler, zobaczysz, że druga aktualizacja nie jest nawet wysyłana do serwera.

Zostało to poprawione w programie .NET Framework 4.0, dlatego zgłaszany jest wyjątek, który będzie zawierał komunikat typu "Zapytanie zostało skompilowane dla innego źródła mapowania niż skojarzone z określonym obiektem DataContext.", I nie będzie po prostu bezgłośnie zawodzi. Jednak podany kod działa poprawnie, ponieważ używa tego samego statycznego źródła mapowania dla wszystkich instancji LinqTestDataContext.

zasadzie to był zawsze problem, ale używane na niepowodzenie cicho, po prostu sprawiło, że brak wyraźnego w .NET 4.

0

ja też w obliczu podobnego problemu. Usunąłem statyczne ze skompilowanych zapytań, działa dobrze. Chociaż muszę jeszcze dowiedzieć się, jak wiele ma to wpływ na wydajność.

1

Spędziłem dużo czasu, patrząc na to i jak zachowanie zostało zmienione w .NET 4.0. Mam szczegółowo moje odkrycia dokładniej w moim blogu tutaj:

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

Szorstka z nich jest: Microsoft dokonane zmiany, aby chronić ludzi przed robieniem czegoś głupiego (Ponowne użycie skompilowany zapytanie pomiędzy różnymi odwzorowań), ale wydaje się, że zepsuło to znaczną korzyść z wydajności (ponowne wykorzystanie skompilowanego zapytania między różnymi kontekstami SAME MAPPING, ale różne instancje odwzorowania).

Używanie getter lub CompiledQuery, który jest członkiem twojej klasy, spowoduje tylko ciągłą rekompilację i brak realnej wydajności.