2017-03-18 214 views
3

我最近接触到实体框架6 caching mechanism。 正如我们可能从this article得出的那样,它是以第一杠的方式做的。我们是否需要外部缓存机制,而EF 6是否使用缓存?

我们的系统使用与MemoryCache沿EF 6(第一代码)来提高性能。

我们使用MemoryCache主要的原因是因为我们需要在每一个页面请求的执行强烈的查询。我们对每个页面请求执行此查询x3次(在最坏的情况下),因为有客户端回调。

我不知道,如果我们仍然需要使用MemoryCache机制如果EF 6已经在使用一个。

值得一说的是,我们不使用任何特殊的缓存功能或缓存依赖。只是一个简单的MemoryCache超时。

回答

3

英孚在上下文中缓存的实体的事实是没有办法“真正的”缓存,由于种种原因更换:

  1. 你不应该重复使用一个以上的逻辑运算EF背景下,因为EF上下文表示工作单元,因此应根据此模式使用。而且,即使由于某种原因在多个操作中重用上下文 - 您绝对不能在多线程环境中执行此操作,例如Web服务器应用程序。

  2. 它不会阻止你做多个查询相同数据到数据库,例如:

    var entity1 = ctx.Entities.Where(c => c.Id == 1).First(); 
    var entity2 = ctx.Entities.Where(c => c.Id == 1).First(); 
    

    这仍将执行两个查询到您的数据库,尽管查询是相同的并返回相同的实体。所以在这里通常意义上没有什么是“缓存”的。但请注意,即使两个查询之间的数据库行已更改,两个查询都将返回相同的实体。这就是EF上下文“缓存”的含义。它会执行两次数据库查询,但是第二次在评估结果时会注意到已经存在具有与上下文相同的键的实体。因此,它将返回此现有(“缓存”)实体,并将忽略第二个查询返回的新值(如果有的话)。这种行为是不能在多个操作之间重用上下文的另一个原因(尽管您不应该这样做)。

所以,如果你想降低您的数据库负载 - 你使用任何适合您的需求(从简单到InMemoryCache缓存EF提供分布式memcached的实例)使用二级缓存。

+0

谢谢你。我对第二部分感到惊讶,如果我执行一个查询,然后更改数据库中的值并再次执行相同的查询,它会带给我相同的结果,而不会发生更改。它是否仍然在第二次提到DB?虽然它给了我未更新的数据? – Jacob

+0

@Jacob我更新了那部分来回答你的问题,希望它很清楚。如果您仍然有这方面的担忧 - 很容易验证自己 - 只需设置日志记录(如'context.Database.Log = Console.WriteLine'),然后执行相同的查询两次,您将看到执行了两个数据库查询。 – Evk

+0

最好解释。非常感谢你! – Jacob

4

EF只实现了所谓的实体一级高速缓存,它保存了已经在上下文的续航时间已经检索到的实体,所以当你问该实体,第二次返回从上下文中的实体。您需要的是二级缓存,但EF不能植入此功能。例如,NCache实现了一个美妙的缓存体系结构,并为EF提供了一个二级缓存提供程序。不在其开源版本中。