Я создаю интернет-магазин, используя ASP.Net Core
(Razor Pages) с EF Core
. Чтобы ускорить вычисления, я кеширую все продукты (~ 100.000). Информация поступает из нашей базы данных.
Модели
class ProductInformation{
// some information about how to display a product
public string productnumber {get; set;}
public Product product {get; set;}
}
class Product{
public string productnumber {get; set;}
public decimal price {get; set;}
public Category category {get; set}
// and a lot more...
}
В моем DBContext я определяю, что каждая PoductInformation имеет точный продукт.
метод кэширования
private readonly IMemoryCache _cache; // is set in the constructor
private readonly DBContext _dbContext; // is set in the constructor
public List<ProductInformation> GetProductInformationList(){
List<ProductInformation> = _cache.GetOrCreate("ProductInformations", entry =>
{
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(24);
List<ProductInformation> list =_dbContext.ProductInformation.ToList();
// do a lot of calculations on the list-elements
return list;
});
}
Весь метод кэширования занимает 100-120 секунд. Теперь другая система обновляет мою цену в БД для одного продукта, и, конечно, я хочу показать правильную цену этого продукта в моем интернет-магазине. Давайте предположим, что я хочу проверять цену каждые 15 минут.
Решения - пробовали, но не удовлетворяли
Метод 1
Я могу установить кэшированиеВесь список до 15 минут, это будет работать, но это не то, что я хочу. Обновление всего кэша происходит медленно и не нужно. 99,9% данных не изменились.
Метод 2
Внутри моей модели ProductInformation я создаю метод, который обновляет Продукт:
class ProductInformation{
// some information about how to display a product
public string productnumber {get; set;}
public Product product {get; set;}
pubic DateTime ProductTimeStamp {get; set;}
public UpdateProduct(){
// If ProductTimeStamp is more than 15 minutes in the past
// get Product from the DB
// and update the timestamp
}
}
Везде, где я отображаю ProductInformation, я звоню UpdateProduct()
. Затем я проверяю только «старые» цены из отображаемых продуктов. Это гораздо эффективнее, чем пересчитать весь кеш. Но теперь мне нужно соединение с БД внутри моей ProductInformation (которая кешируется). Я не могу заставить это работать.
Метод 3
Поскольку проблема в методе 2 заключается в том, что у меня нет подключения к БД, я могу взятьUpdateProduct()
метод вне модели и поместите его в мой репозиторий, где у меня есть соединение с БД. Везде, где я отображаю ProdctInformation, мне нужно вызывать что-то вроде _proudctRepository.UpdateProduct(ref ProductInformation);
. Этот метод выглядит следующим образом:
public void UpdateProduct(ref ProductInformation pi){
pi.Product = _dbContext.Product.Where(p => p.productnumber == pi.productnumber);
// Of course I also need to do the calculations from the caching-method in GetProductInformationList()
}
Но это не так. Entity Framework организовал для меня связь между ProductInformation и Product, возможно ли тогда переопределить Product таким образом? Я думаю, что это не тот путь.
Вопрос
Я думаю, что многие люди используют IMemoryCaching для одинаковых ситуаций (когда вы хотите обновить только один элемент в кэшированном Списке или просто некоторыеэлементы (цена / акции / ...) элемента кэшированного списка). Как мы можем справиться с этим?