НЕ ИСПОЛЬЗУЙТЕ код в этой статье. Я не знаю, что этот человек курил, но код в основном читает все содержимое таблицы и помещает его в кэш-память. Я не могу придумать гораздо худший вариант для нетривиальной таблицы (а 35 000 записей определенно нетривиальны).
Linq to SQL не кеширует запросы. Linq to SQL отслеживает определенные объекты , полученные по запросам с использованием их первичных ключей. Это означает, что если вы:
- Запрос
DataContext
для некоторых объектов;
- Измените эти сущности (но пока не звоните
SubmitChanges
);
- Запустите другой запрос, который извлекает те же сущности.
Тогда результаты # 3 выше будут теми же сущностями, которые вы извлекли в (1) с изменениями, которые вы внесли в (2) - другими словами, вы получите обратно существующие сущности, которые уже отслеживает Linq, а не старые сущности из базы данных. Но он все равно должен выполнить запрос , чтобы узнать, какие объекты загружать; отслеживание изменений не является оптимизацией производительности.
Если ваш запрос к базе данных занимает более 100 мс, то проблема почти наверняка на стороне базы данных. Вероятно, у вас нет соответствующих индексов для столбцов, по которым вы запрашиваете. Если вы хотите кэшировать вместо решения проблемы перфорирования БД, вам необходимо кэшировать результаты конкретных запросов , что вы должны сделать, указав их в параметрах, использованных для создания запроса. Например (C #):
IEnumerable<Batch> GetBatches(DateTime startDate, DateTime endDate,
Decimal amount)
{
string cacheKey = string.Format("GetBatches-{0}-{1}-{2}",
startDate, endDate, amount);
IEnumerable<Batch> results = Cache[cacheKey];
if (results != null)
{
return results;
}
results = <LINQ QUERY HERE>.ToList();
Cache.Add(cacheKey, results, ...);
return results;
}
Это нормально, если результаты нельзя изменить, пока элемент находится в кеше, или если вам не нужны устаревшие результаты. Если это проблема, тогда она станет намного сложнее, и я не буду вдаваться во все тонкости здесь.
Суть в том, что "кэширование" каждой отдельной записи в таблице вообще не кэширует, а превращает эффективную реляционную базу данных (SQL Server) в неаккуратную, неэффективную базу данных в памяти (общий список в кэше) , Не кэшируйте таблицы , кэшируйте запросы , если вам нужно, и прежде чем вы даже решите это сделать, попробуйте решить проблему производительности в самой базе данных.
Для протокола я должен также отметить, что кто-то, кажется, реализовал форму кэширования , основанную на самом IQueryable<T>
. Я не тестировал этот метод, и я не уверен, насколько проще было бы использовать его на практике, чем описанное выше (вам все равно придется специально его использовать, он не автоматический), но я перечисляю его как возможная альтернатива.