【问题标题】:Get MemoryCache in Different Controller for Entity Framework Database在实体框架数据库的不同控制器中获取 MemoryCache
【发布时间】:2019-10-05 20:04:34
【问题描述】:

我从 Entity Framework 数据库中获取小的查找表值并存储在 MemoryCache 中。目前使用两种方式,常规 memoryCache 和 Singleton MemoryContainer 见此处Asp.Net Core: Use memory cache outside controller

Home Controller 中,这会将 ProductTypes 保存在 MemoryCache 中,我们可以看到值正确存储在调试窗口中(ProductType、ProductName 等)。

public class HomeController : Controller
{
    public IMemoryCache _memoryCache;
    public readonly StoreContext _storeContext;
    public MemoryContainer _memoryContainer;

    public HomeController(StoreContext storeContext, IMemoryCache memoryCache, MemoryContainer memoryContainer)
    {
        _storeContext= storeContext;
        _memoryCache = memoryCache;
        _memoryContainer = memoryContainer;
    }

    public IActionResult Index()
    {
        var productTypes = storeContext.ProductTypes;
        _memoryCache.Set("ProductTypesKey", productTypes );
        _memoryContainer._memoryCache.Set("ProductTypesKey2", test);
        return View();   //both values store correctly
    }

那么当去ProductController时,

public class ProductsController : Controller
{
    public StoreContext _storeContext;
    public IMemoryCache _memoryCache;
    public MemoryContainer _memoryContainer;

    public ProductsController(StoreContext storeContext, IMemoryCache memoryCache, MemoryContainer memoryContainer)
    {
        _storeContext = storeContext;
        _memoryCache = memoryCache;
        _memoryContainer = memoryContainer;
    }

    public async Task<IActionResult> Details(int? id)
    {
        var test =  _memoryCache.Get<DbSet<ProductTypes>>("ProductTypesKey");
        var test2 = _memoryContainer._memoryCache.Get<DbSet<ProductTypes>>("ProductTypesKey2");

我在两个内存缓存中都看到以下错误结果,如何解决?

如何确保 MemoryCache 能够通过 DbContext 正确获取/存储,无论从控制器到控制器如何?

“无法访问已释放的对象。此错误的常见原因是释放从依赖注入中解析的上下文,然后尝试在应用程序的其他地方使用相同的上下文实例。如果您调用 Dispose( ) 在上下文中,或将上下文包装在 using 语句中。如果使用依赖注入,则应让依赖注入容器负责处理上下文实例。\r\n对象名称:'StoreContext'。"

其他代码:

public class MemoryContainer
{
    public IMemoryCache _memoryCache { get; set; }
    public MemoryContainer(IMemoryCache memoryCache)
    {
        _memoryCache = memoryCache;
    }
}

Startup.cs

services.AddMemoryCache();
services.AddSingleton<MemoryContainer>();

其他资源:

MVC Net Core Pass MemoryCache to All Controllers

【问题讨论】:

  • 您显示的代码看起来不错。问:你在使用这个 StoreContext 和/或 MemoryCache 的任何地方都有一个“使用”块吗?
  • 我明白了 - 谢谢你的详细说明。问:您在上面提到的Singleton 想法对您来说是一个好的解决方案吗?

标签: c# entity-framework asp.net-core caching .net-core


【解决方案1】:

DbSet&lt;T&gt; 实现了 IQueryable,因此这些 ProductType 在具体化之前不会真正在您的应用程序中。

一个简单的ToList() 就可以完成这项工作:

var productTypes = storeContext.ProductTypes.ToList();

然后,在另一个控制器内部:

var test =  _memoryCache.Get<List<ProductTypes>>("ProductTypesKey");

在没有任何过滤器的情况下在DbSet 上调用ToList() 并不是所有情况下的最佳方法,因为它会加载DbSet 后面的整个sql 表。但是,我想这就是您想要做的事情,只要确保您从不在包含大量数据的表上执行此操作即可。

注意:您在调试窗口中看到数据,因为扩展 IQueryable 结果实际上执行 sql 查询。

【讨论】:

    猜你喜欢
    • 2012-09-12
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多