2015-12-04 49 views
1

我知道DbContext的缓存不是个好主意。但我想做得很好。你怎么看待这种方式?DbContext caching

public class Context : DbContext 
{ 
    private Context() 
    { 
    } 

    private static WeakReference<Context> _cachedContext; 

    public Context Instance 
    { 
     get 
     { 
      Context context; 
      if (!_cachedContext.TryGetTarget(out context)) 
      { 
       context = new Context(); 
       _cachedContext.SetTarget(context); 
      } 
      return context; 
     } 
    } 
} 

此代码计划在客户端不使用IDisposable.Dispose调用时使用。除单态(反)模式外,这可能导致什么问题?谢谢。

+1

上下文的一般经验法则是创建尽可能晚,并尽可能快地杀死它。没有理由让它挂在身边。 – DavidG

+0

为什么要缓存DbContext类?没有理由为什么你应该这样做。还有其他方法可以像DI容器一样管理DbContext类的处理(unity只是一个名称)。 – hbulens

+0

你的WeakReference单身人士看起来超级狡猾。如果挂在上下文中的唯一东西是WeakReference,那么它将符合GC的条件。你需要一个强大的参考,而不是一个弱的参考。实际上,正因为如此,你的架构会比你以为你提出的架构意外地更好,因为偶尔你会得到一个新的上下文(但也可能是一些非常混乱的错误)。更好的是,不要拘泥于你的背景。这是一个比单身更重要的反模式。 – spender

回答

8

DbContext是一个缓存。长时间保持它是一个可怕的想法......它会慢慢地将应用程序的内存挂在数据上,而这些数据可能已经陈旧了。

它的设计并非按照您的建议使用。

不要这样做。

A DbContext是应该在尽可能小的范围内使用和处置的瞬态对象。

using(var ctx = new MyDbContext()) 
{ 
     //make some changes 
     ctx.SaveChanges(); 
} 

这就是它的设计原理。正确使用它。

+1

@CodeCaster达成了强烈的共识:) – spender

+0

我没有保留一个对象。我只保留弱点。它并不妨碍垃圾收集器的工作。但根据你的提示,我需要避免上面的缓存方式(通过弱引用)。好。我认为,当我创建DbContext的新实例时,我有一个新的连接到数据库,它可以影响性能 – Serg046

+0

@ Serg046新的DbContext不会创建到数据库的新连接。与数据库的连接由框架的其他部分管理...... DbContext将借用池中的连接。这会导致另一个问题,如果您不迅速处理您的上下文...连接池可能会变得困惑和耗尽。 – spender

5

This is an XY problem为什么要“缓存”DbContext?你认为你会从中得到什么好处?

你不应该这样做,永远。这个班不是为了这个。它会导致性能问题(取消您想要获得的好处)和持续性错误 - 您无法再使用此上下文保存实体,因为更改跟踪器持有实体。

Correct usage of EF's DBContext in ASP.NET MVC application with Castle WindsorWorking with DbContextManaging DbContext the right way with Entity Framework 6: an in-depth guide,其他数千次点击的Manage the lifetime of dbContext或任何对在网上搜索“的DbContext一生实体框架”。

如果您想要缓存数据,则改为缓存记录本身。现有的解决方案(代码和库)可以帮助您实现这一目标,称为“二级缓存”。无需自己写。例如参见How to make Entity Framework cache some objects