Кэширование результатов с использованием Massive micro-ORM
Я использую Massive микро-ORM с новым проектом. Я добавил кеширование, и все это заработало - пока я не понял, что кэшированные объекты (динамические) все еще запрашивают базу данных. Это убивает весь смысл кеширования.
Что было бы самым простым способом отключить набор результатов из базы данных. Почти все звонки доступны только для чтения.
Я использую такой код для запроса записей:
public static dynamic GetActive()
{
return Caching.LoadFromCache("Units_GetActive", 120,
() =>
{
dynamic tbl = new Units();
return tbl.Find(Enabled: 1, orderby: "SortOrder");
});
}
Мой кеширующий код выглядит так:
public static dynamic LoadFromCache(string cacheKey, int secondsToCache, Func<object> query)
{
object tocache = null;
// result will always get the value here
// tocache will only have the value when it was pulled from our method
object result = MemoryCache.Default[cacheKey] ?? (tocache = query.Invoke());
if (secondsToCache > 0)
{
if (tocache != null) // only save to cache if it wasn't there
MemoryCache.Default.Add(cacheKey, tocache, DateTime.UtcNow.AddSeconds(secondsToCache));
}
else
{
// remove from cache only if secondsToCache was zero or less
MemoryCache.Default.Remove(cacheKey);
}
return result;
}
Кеширующий код работает. Проблема в том, что динамический объект возвращается (IEnumerable<dynamic>
) открывает другое соединение с базой данных.
Идеи?
1 ответ
У Тима Медора была правильная идея.
Я изменил свой кеширующий код на это:
public static dynamic LoadFromCache(string cacheKey, int secondsToCache, Func<object> query)
{
object tocache = null;
// result will always get the value here
// tocache will only have the value when it was pulled from our method
object result = MemoryCache.Default[cacheKey] ?? (tocache = query.Invoke());
if (secondsToCache > 0)
{
// If this came from Massive, we need to get the list instead of opening a
// database connection each time we enumerate. I check the type, because other things
// are stored.
if (tocache is IEnumerable<dynamic>)
{
tocache = ((IEnumerable<dynamic>)tocache).ToList<dynamic>();
result = tocache;
}
if (tocache != null) // only save to cache if it wasn't there
MemoryCache.Default.Add(cacheKey, tocache, DateTime.UtcNow.AddSeconds(secondsToCache));
}
else
{
// remove from cache only if secondsToCache was zero or less
MemoryCache.Default.Remove(cacheKey);
}
return result;
}
ToList<dynamic>()
была ключевой частью. Кажется, теперь работает как ожидалось. ToList<T>
является методом расширения в System.Linq
Пространство имен.