Entity Framework Code First - Сокращение циклов с помощью .Load () и .Local - PullRequest
2 голосов
/ 30 марта 2011

Я настраиваю новое приложение, используя Entity Framework Code Fist, и я ищу способы попытаться максимально сократить количество обращений к SQL Server.

Когда я впервые прочитал о свойстве .Local здесь , я очень обрадовался возможности вывести целые графы объектов на ранних этапах моего конвейера обработки, а затем использовать .Local позже, не беспокоясь о том, чтобы вызвать Стоимость дополнительных поездок туда и обратно.

Теперь, когда я поэкспериментирую с этим, мне интересно, есть ли способ снять все данные, которые мне нужны для одного запроса, в одну поездку. Например, у меня есть веб-страница с несколькими списками, новостями, событиями и дискуссиями. Есть ли способ, которым я могу записать записи их 3 несвязанных исходных таблиц в DbContext за один раз? Вы все там, в сети, думаете, что это прекрасно, когда одна страница делает 20 обращений к серверу БД? Я полагаю, что при наличии надлежащего механизма кэширования эта проблема может быть смягчена.

Я наткнулся на пару из трещин при возврате нескольких результатов запросов EF за один цикл, но я не уверен, что сложность и зрелость этих видов решений стоит отдачи.

В целом, с точки зрения составления наборов данных, которые должны быть переданы на контроллеры MVC, считаете ли вы, что лучше просто сделать отдельный запрос для каждого набора записей, который вам нужен, а затем беспокоиться о большей части производительности позже на уровне кэширования, используя либо поставщик кэширования EF или кэширование asp.net?

Ответы [ 3 ]

3 голосов
/ 30 марта 2011

Совершенно нормально сделать несколько вызовов БД, если они вам нужны. Если вы боитесь нескольких циклических переходов, вы можете либо написать хранимую процедуру и вернуть несколько результирующих наборов (не работает с функциями EF по умолчанию), либо выполнить ваши запросы асинхронно (запускать несколько дизъюнктных запросов одновременно). Загрузка нереализованных данных одним запросом linq невозможна.

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

0 голосов
/ 16 августа 2011

Мое эмпирическое правило заключается в том, что выполнение вызова для каждой коллекции объектов, которые вы хотите получить, в порядке. Выполнение вызова для каждой строки, которую вы хотите получить, плохо. Если вашей веб-странице требуется 20 коллекций, тогда 20 звонков - это нормально.

При этом сокращение этого значения до одного вызова не составит труда, если вы используете метод Translate. Код примерно так будет работать

var reader = GetADataReader(sql);
var firstCollection = context.Translate<whatever1>(reader);
reader.NextResult();
var secondCollection = context.Translate<whateve2r>(reader);
etc

Большим недостатком этого является то, что если вы поместите свой sql в хранимый процесс, то ваши хранимые процессы станут более специфичными для ваших веб-страниц, а не для более общего назначения. Это не конец света, если у вас есть хороший доступ к вашей базе данных. В противном случае вы можете просто определить свой sql в коде.

0 голосов
/ 30 марта 2011

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

Помните: «Преждевременная оптимизация - корень всего зла».

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