Кэширование Linq Query Question - PullRequest
       3

Кэширование Linq Query Question

3 голосов
/ 02 февраля 2011

Я создаю форумный пакет для cms и смотрю на кеширование некоторых запросов, чтобы повысить производительность, но я не уверен, поможет ли приведенное ниже кеширование / сделает то, что должно быть ниже (кстати: Cachehelper простой вспомогательный класс, который просто добавляет и удаляет из кэша)

          // Set cache variables
        IEnumerable<ForumTopic> maintopics;

        if (!CacheHelper.Get(topicCacheKey, out maintopics))
        {
            // Now get topics
            maintopics = from t in u.ForumTopics
                          where t.ParentNodeId == CurrentNode.Id
                          orderby t.ForumTopicLastPost descending
                          select t;
            // Add to cache
            CacheHelper.Add(maintopics, topicCacheKey);
        }
        //End Cache

        // Pass to my pager helper
        var pagedResults = new PaginatedList<ForumTopic>(maintopics, p ?? 0, Convert.ToInt32(Settings.ForumTopicsPerPage));

        // Now bind
        rptTopicList.DataSource = pagedResults;
        rptTopicList.DataBind();

Не работает ли linq только при перечислении? Так что вышесказанное не сработает, не так ли? как только перечисляется, когда я передаю его помощнику по поисковому вызову, который .Take () представляет собой определенное количество записей, основанное на значении строки запроса 'p'

Ответы [ 3 ]

2 голосов
/ 02 февраля 2011

Вам необходимо перечислить свои результаты, например, вызвав метод ToList().

maintopics = from t in u.ForumTopics
             where t.ParentNodeId == CurrentNode.Id
             orderby t.ForumTopicLastPost descending
             select t;
// Add to cache
CacheHelper.Add(maintopics.ToList(), topicCacheKey);
0 голосов
/ 02 февраля 2011

Да, вам нужно перечислить ваши результаты. Linq не будет оценивать ваш запрос, пока вы не перечислите результаты.

Если вам нужна общая стратегия кэширования для Linq, вот отличный учебник:

http://petemontgomery.wordpress.com/2008/08/07/caching-the-results-of-linq-queries/

Конечной целью является возможность автоматически генерировать уникальные ключи кеша для любого запроса Linq.

0 голосов
/ 02 февраля 2011

Мой опыт работы с Linq-to-Sql заключается в том, что он не является сверхпроизводительным, когда вы начинаете входить в сложные объекты и / или объединения.

Первый шаг - настроить LoadOptions для текста данных.Это приведет к принудительному объединению, чтобы отозвать полную запись.Это была проблема в системе отслеживания билетов, которую я написал.Я отображал список из 10 билетов и увидел, что по сети поступило около 70 запросов.У меня был тикет-> субстрат-> статус.Из-за ленивой инициализации L2S каждый внешний ключ для каждого объекта, на который я ссылался в сетке, вызывал новый запрос.Вот сообщение в блоге (не мое) на эту тему (MSDN был слабым): http://oakleafblog.blogspot.com/2007/08/linq-to-sql-query-execution-with.html

Следующий вариант - создать предварительно скомпилированные запросы Linq.Я должен был сделать это с большими соединениями.Вот еще одна запись в блоге на эту тему: http://aspguy.wordpress.com/2008/08/15/speed-up-linq-to-sql-with-compiled-linq-queries/

Следующий вариант - преобразовать вещи в хранимые процедуры.Это наверняка усложняет программирование и развертывание, но для сложных запросов, когда вам нужен только поднабор данных, они будут на несколько порядков быстрее.

Причина, по которой я это поднимаю, заключается в том, что вы говоритео кешировании вещей (почему бы не использовать встроенный Cache в ASP.NET?) может вызвать у вас много головной боли в долгосрочной перспективе.Я бы порекомендовал собрать вашу систему и затем запустить трассировку SQL, чтобы увидеть, где проблемы с производительностью вашей базы данных, а затем построить оптимизацию вокруг этого.Вы можете обнаружить, что ваши реальные проблемы не в «топ-10 тем», а в других, гораздо более простых для устранения областях.

...