Веб-сервисы Ninject и WCF замедляют работу Entity Framework - PullRequest
0 голосов
/ 15 мая 2019

У меня есть следующая настройка: веб-службы WCF, размещенные в IIS.Entity Framework 6 используется для извлечения данных из БД.Веб-службы инициализируются в Global.asax.cs, который наследуется от NinjectHttpApplication (поэтому мы используем ninject для внедрения зависимостей).В этом NinjectHttpApplication в методе CreateKernel мы связываем EF DbContext следующим образом:

protected override IKernel CreateKernel()
{
    var kernel = new StandardKernel();
    kernel.Bind<DbContext>().To<MyCustomContext>().InTransientScope();
    return kernel;
}

Затем при каждом вызове службы контекст получается следующим образом в его констуркторе:

_context = kernel.Get<DbContext>();    

Затем служба извлекает данные из БД следующим образом:

data = _context.Set<TEntity>().Where(<whatever filter>);

Сказав это, моя проблема заключается в следующем: у меня есть служба, которая вызывается много раз (со сложной и длительнойзапрос с множественными объединениями), и каждый раз, когда он вызывается, EF требуются годы, чтобы произвести SQL для отправки в БД в результате кода Linq To Entities, который я кодировал.Выполнение запроса в БД - ничто (600 миллисекунд), но EF тратит много времени на создание SQL-кода каждый раз, когда вызывается эта служба.Я подозреваю, что это из-за kernel.Bind<DbContext>().To<MyContext>().InTransientScope(), который заставляет EF создавать новый экземпляр DbContext каждый раз, когда происходит вызов.

Я провел несколько тестов с использованием UnitTests, и его поведение совершенно иное: если вы создаете экземпляр службы несколько раз из одного и того же метода модульного теста и вызываете его, EF потребуется много времени, чтобы выполнить запрос только первымвремя, тогда не требуется времени для создания SQL из последующих вызовов (тот же запрос, но с другими параметрами для фильтрации данных для извлечения).Из модульного теста CreateKernel (), конечно, вызывается только один раз в методе Initialize() (как в веб-сервисе в global.asax.cs), поэтому я не знаю, что провоцирует эту огромную задержку.Я подозреваю, что EF способен сохранять / кэшировать запрос, предварительно скомпилированный с помощью модульного теста, но не в реальном веб-приложении.Любая подсказка, почему?

Обратите внимание, что запрос Linq to Entities параметризован (строки и дата являются параметрами).

Любая помощь очень ценится.

1 Ответ

0 голосов
/ 17 мая 2019

Я считаю, что вы связываете свой DbContext в InTransientScope, что означает, что каждый раз, когда вы получаете Dbcontext от ninject, он будет создавать новый DbContext для вас.

Вы можете рассмотреть возможность использования InThreadScope () вместо InTransientScope (), это означает, что ninject вернет тот же экземпляр, когда он находится в том же потоке.

Существует также область видимости SingleTon, что означает, что всегда нужно возвращать один и тот же экземпляр, но это сделает dbcontext слишком большим.

...