【问题标题】:Weird behavior of Entity Framework's ObjectContext (v4.0)实体框架的 ObjectContext (v4.0) 的奇怪行为
【发布时间】:2011-01-05 19:04:40
【问题描述】:

我的 NHibernate 背景是 Entity Framework v4.0。当我将实体加载到 ObjectContext 中时,我希望只要 ObjectContext 存在(“一级缓存”),它们就会被缓存在那里。因此,如果第二次执行相同的查询,则对象已经在 ObjectContext 中,不应再次加载。

看看这个查询:

        using (var context = new Model1Container()) {
            //load entities from DB
            var entities = context.Entity1Set.ToArray();
            //entities should now be cached in the context (1st level cache)

            //why does this call not use the cached items?
            entities = context.Entity1Set.ToArray();
        }

在 SQL Server Profiler 中,我可以清楚地看到两个 ToArray() 调用都会触发数据库查询。为什么第二个查询需要数据库往返,而不是 NHibernate 行为?

谢谢!

【问题讨论】:

    标签: .net entity-framework


    【解决方案1】:

    好问题。我从未使用过 NHibernate,但我在过去一年左右一直在使用 Entity Framework。

    在某些方面,您描述的行为对我来说是有意义的。如果数据库中的数据在调用之间发生变化怎么办?例如,Entity Framework 必须重新查询数据库以检查是否有任何新行已添加到数据库表中。

    但是,对结果执行 LINQ 查询不需要再次往返数据库,因为 Entity Framework 将从 ObjectContext 中提取现有实体。

     var newEntities = entities.Where(x=>x.id==1).ToList();
     var newEntities2 = entities.Where(x=>x.id==1).ToList();
    

    【讨论】:

    • 同意,根据我的经验,与上下文中已经存在的特定 ID 相关的操作不需要再次往返数据库。诸如给我所有项目之类的一般操作将始终转到数据库。
    • 这并不奇怪,因为如果您在 'entities' 数组上执行 .Where() 方法,您实际上是在使用 LINQ to Objects 而不是 LINQ to Entities。我想知道 LINQ to Entities 是否通常能够缓存查询结果
    • 另一件事:如果我们的 ObjectContext 存在的时间太长以至于数据库中的数据在调用之间可能会发生变化,我们可以使用 ObjectContext.Refresh。大多数情况下,ObjectContext 的生命周期很短,所以我们并不关心数据库在其生命周期内的变化
    【解决方案2】:

    EF 4.0 不支持任何形式的缓存,NHibernate 不支持一级缓存和二级缓存。

    在 EF 4.1 中实现了一个类似于 NHibernate 一级缓存的功能。

    EF 4.1 Local Data

    HTH

    丽安娜

    【讨论】:

      猜你喜欢
      • 2015-09-07
      • 2013-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-04
      相关资源
      最近更新 更多