Проблема скомпилированного запроса DataContext в .NET 4 - PullRequest
6 голосов
/ 11 октября 2010

Мой проект (слой пользовательского интерфейса asp.mvc) был разработан с использованием .NET 3.5. После обновления до .NET 4.0 у меня возникла проблема со скомпилированными запросами:

 [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

Каждый раз, когда я запускаю свой запрос, я передаю свой контекст

return StaticQueries.getTopFiveOrders(mContext, int howMany);


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

Ошибка возникает при втором запросе.

Ответы [ 3 ]

4 голосов
/ 22 ноября 2010

Это связано с изменением способа работы скомпилированных запросов.

Теперь их нужно всегда запускать в одном и том же контексте.

Эта страница подключения Microsoft объясняет, почему было внесено изменение:

Проблема в этом случае вызвана тем фактом, что CompiledQuery требует, чтобы один и тот же источник отображения использовался для всех выполнений.В примере кода, который вы используете для воспроизведения проблемы, различные экземпляры DataContext каждый раз используют новый источник сопоставления, но запрос не сообщает об этом и просто молча завершается ошибкой.Если вы используете свойство DataContext.Log или другое ведение журнала, например, SQL Server Profiler, вы увидите, что второе ОБНОВЛЕНИЕ даже не отправляется на сервер.

Это было исправлено в .NET Framework 4.0, поэтомусообщается об исключении, которое будет содержать сообщение типа «Запрос был скомпилирован для источника сопоставления, отличного от того, который связан с указанным DataContext.», и он просто не завершится с ошибкой.Однако указанный вами код, который работает, является правильным способом сделать это, потому что он использует один и тот же источник статического сопоставления для всех экземпляров LinqTestDataContext.молча, они просто сделали ошибку явной в .NET 4.

2 голосов
/ 20 января 2014

Я потратил много времени на изучение этого и того, как изменилось поведение в .NET 4.0. Я подробно изложил свои выводы в своем блоге здесь:

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

Суть в том, что Microsoft внесла изменения, чтобы защитить людей от каких-то глупостей (повторное использование скомпилированного запроса между различными сопоставлениями), но, похоже, сломало основное преимущество в производительности (повторное использование скомпилированного запроса в разных контекстах ОДНОГО MAPPING, но разные экземпляры отображения).

Использование методов получения или CompiledQuery, являющегося членом вашего класса, приведет только к постоянной перекомпиляции и не принесет реального выигрыша в производительности.

0 голосов
/ 04 ноября 2011

Я тоже сталкивался с подобной проблемой.Я удалил статику из скомпилированных запросов, она отлично работает.Хотя мне еще предстоит выяснить, насколько это влияет на производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...