ASP.NET Core - 使用 EF Core 更新 IMemoryCache 中缓存 List<Element> 的 1 元素

筛选

我正在使用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 分钟检查一次价格。

解决方案 - 尝试过但不满意

方法一

我可以将整个列表的缓存设置为 15 分钟,这会起作用,但这不是我想要的。刷新整个缓存很慢而且没有必要。99.9%的数据没有变化。

方法二

在我的模型 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 中建立一个数据库连接(即缓存)。我不能让它工作。

方法三

由于方法 2 中的问题是我没有 DB 连接,因此我可以将UpdateProduct()方法出模型并将其放入我有 DB 连接的存储库中。在我显示 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()
}

但这感觉不对。实体框架为我组织了 ProductInformation 和 Product 之间的连接,那么是否可以通过这种方式重新定义 Product?我认为这不是要走的路。

问题

我认为很多人在相同的情况下使用 IMemoryCaching(您只想更新缓存列表中的单个元素或缓存列表元素的某些元素(价格/股票/...))。我们该如何处理?

德米特里

1) 将LastChanged(datetime[offset]) 列添加到您的Product数据库中,并要求“另一个系统”在更新您的价格时也更新它。有了这个,您可以轻松地保存Max(LastChanged)在缓存中并仅查询更改的产品,减少更新的时间和大小,并且您可以更频繁地执行此操作。

2)将数据放入缓存时添加AsNoTracking您不会将它们更新回 DB(我猜),因此无跟踪会稍微加快速度。此外,这将使您无需担心ProductInformation- ProductEF 关系,因为 EF 无论如何都不会跟踪它们,并且pi.Product将是一个通常的对象保持属性,没有任何隐藏的魔法。

3) 在每个页面渲染时检查价格更新是不好的。更新应该在其他线程/后台运行。设置一些后台任务,以检查更新的价格并将更新的对象重新加载到缓存中 - 使用 (1) 您可以每 5 分钟或更短时间运行一次更新。在此处通过依赖注入检查DbContext 以获取后台任务以获取 DbContext。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用EF Core更新ASP.NET 5中的dbcontext脚手架?

ASP.NET Core中的Redis缓存

.NET Core中无法使用EF更新数据库

使用.net Core / EF Core的SQL Server 2016与ASP MVC应用中的列加密

asp.net core / EF-Core mysql更新数据库错误

VS 2015中的Asp.net Core EF

IMemoryCache中的ASP.NET Core清除缓存(由CacheExtensions类的Set方法设置)

将EF Core与ASP.NET Core MVC和Sqlite结合使用-正确的类结构

为什么将DBContext放入IMemoryCache(.NET Core / EF Core)后将其丢弃

XUnit如何模拟IMemoryCache ASP.NET Core

ASP.NET Core MemoryCache-使用中的更新项

.NET Core库中的EF Core

无法在asp.net core 2.2应用程序中使用ef core 2.2通过UserManager <TUser>更新用户

在ASP.NET Core WebApplicationFactory中重写EF Core DbContext

AspNetCoreRateLimit .NET Core 3.0-无法解析参数IMemoryCache缓存

如果我更改从Net Core IMemoryCache获得的对象,它会更新其在缓存中的状态吗?

如何使用EF Core 3.1.5解决ASP.net Core应用程序中的空引用异常?

ASP.NET Core 和 EF Core 1.1 - 使用存储过程显示数据

Asp.Net Core EF Core 多对多关系更新命令

通过 ef 使用存储库和工作单元更新 .net core 中的特定字段

无法使用 EF Core 在 ASP.NET Core 中创建相关实体

Asp.net core,缓存Taghelper和IMemoryCache有什么区别?

使用 Entity Framework Core 更新 ASP.NET Core 中相同字段的并行请求

如果 *not* 依赖注入,可以在 Asp.Net Core 中使用 IMemoryCache 吗?

ASP.NET Core Web API 无法返回使用 EF Core 延迟加载提取的结果

asp net core中的静态文件缓存

如何使用 MemoryCache 类在 asp.net core 中缓存和获取列表

当对象包含外键时,使用 EF Core 在 ASP.NET Core 6 中创建对象

更新数据库引发 FK 级联错误(EF Core / C# / ASP.NET Core)