Сначала давайте поговорим о проблеме. Единственная причина, по которой я могу изобразить, - это избавиться от DbContext befour . ForAll финишировал своей работой, возможно, из другой темы? Но на данный момент я просто догадываюсь.
Я могу дать вам пару предложений о возможной оптимизации кода. Сначала оценка всех котировок с использованием .ToList(), вероятно, имеет некоторое влияние на производительность, если в базе данных много записей, поэтому мой совет заключается в обмене с нетерпением оценкой с помощью курсора SQL. Это может быть достигнуто с использованием любой конструкции/кода, которая использует внутри себя IEnumerable <> и более конкретно .GetEnumerator().
Внутренняя реализация IQueriable <> в EF создает курсор SQL, который довольно быстро. Самое приятное то, что вы можете использовать его с .AsParallel() или Parallel.ForEach, как внутри, так и внутри Enumerators.
Это не очень документированная функция, но если вы запустите профиль SQL Server и выполните приведенный ниже код, вы увидите, что на сервер выполняется только один запрос, а также вы можете заметить, что ОЗУ машины, выполняющей код, не шип, что означает, что он не получает все сразу.
Я нашел некоторую случайную информацию о нем, если вы заинтересуете: https://sqljudo.wordpress.com/2015/02/24/entity-framework-hidden-cursors/
Хотя я использовал этот подход в тех случаях, когда код работает на записи базы данных был довольно тяжелым для простой проекции от одного тип к другому, запустив курсор с помощью .AsParallel(..)
или просто foreach
.
Таким образом, используя
DbContext.Quotes
.AsParallel()
.WithDegreeOfParallelism(...)
.ForAll(...)
должен работать с хорошей производительностью.
Мой второй совет касается доступа к навигационным свойствам в EF с ленивой загрузкой. Это, как вы знаете, приводит к проблеме выбора N + 1. Таким образом, вместо того, чтобы зависеть от EF ленивой оценки в этом случае это будет лучше охотно получать навигационные свойства, поэтому мы можем переписать код примерно как это
DbContext.Quotes
.Include(x => x.QuoteService)
.AsParallel()
.WithDegreeOfParallelism(...)
.ForAll(...)
Таким образом, при доступе к QuoteService навигации свойства EF выиграл» t делать какие-либо дополнительные запросы к Серверу, поэтому это должно значительно улучшить вашу производительность, и, возможно, он сможет исправить исправление нулевой ссылки (я надеюсь)
Общая версия метода .Include (..), который я использую часть пространства имен System.Data.Entity.
Кроме того, если это приемлемо для вашего сценария, вы можете отключить отслеживание изменений, которое принесет вам немного большую производительность. Таким образом, мой окончательный код будет выглядеть так:
var queryViewItems = DbContext.Quotes
.AsNoTracking()
.Include(x => x.QuoteService)
.AsParallel()
.WithDegreeOfParallelism(...)
.Select(x => { ... })
.ToList();
Не 'quotList' a' Список '? Если это так, у него не будет члена, называемого 'QuoteService'. Вы имели в виду 'quote.QuoteService .....'? –
juharr
да, это ошибка. Я исправляю это сейчас. – michael