2011-02-02 3 views
3

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

  // 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() имеет определенное количество записей на основе значения querystring 'p'

ответ

2

Нужно перечислить ваши результаты, например, вызвав метод 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

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

Первым шагом является установка LoadOptions в datacontext. Это приведет к объединению, чтобы отозвать полную запись. Это была проблема в системе отслеживания билетов, которую я написал. Я показывал список из 10 билетов и видел около 70 запросов, которые попадались на провод. У меня был статус ticket-> substatus->. Из-за ленивой инициализации 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/

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

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

0

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

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

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

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