EF DbContext。如何避免缓存?

时间:2013-07-23 14:08:30

标签: entity-framework dbcontext

花了很多时间,但仍然无法理解如何避免在DbContext中进行缓存。

我附上了一些简单案例的实体模型,以证明我的意思。

问题是dbcontext缓存结果。例如,我有下一个用于查询数据库中数据的代码:

using (TestContext ctx = new TestContext())
{
   var res = (from b in ctx.Buildings.Where(x => x.ID == 1)
             select new
             {
                b,
                flats = from f in b.Flats
                        select new
                        {
                           f,
                           people = from p in f.People
                           where p.Archived == false
                           select p
                        }
             }).AsEnumerable().Select(x => x.b).Single();

}

在这种情况下,一切都很好:我得到了我想要的东西(只有Archived == false的人)。

但是如果我在它之后添加另一个查询,例如,查询那些将Archived标志设置为true的人的建筑物,我接下来的事情,我真的无法理解:

  1. 我以前的结果,即 res ,将由数据添加(在那里 将添加Archived == true的人员
  2. 新结果将包含绝对所有人,无论Archived等于
  3. 此查询的代码如下:

    using (TestContext ctx = new TestContext())
    {
       var res = (from b in ctx.Buildings.Where(x => x.ID == 1)
                 select new
                 {
                    b,
                    flats = from f in b.Flats
                            select new
                            {
                               f,
                               people = from p in f.People
                               where p.Archived == false
                               select p
                            }
                 }).AsEnumerable().Select(x => x.b).Single();
    
    
        var newResult = (from b in ctx.Buildings.Where(x => x.ID == 1)
                  select new
                  {
                      b,
                      flats = from f in b.Flats
                              select new
                              {
                                 f,
                                 people = from p in f.People
                                 where p.Archived == true
                                 select p
                               }
                   }).AsEnumerable().Select(x => x.b).Single();
                }
    

    顺便说一下,我在TestContext的构造函数中将 LazyLoadingEnabled 设置为false。

    有人知道如何解决这个问题吗?我怎么能在我的查询中找到我真正在linq中写入实体的内容?

    P.S。 @Ladislav可能会帮忙吗?

    Entity Model

2 个答案:

答案 0 :(得分:8)

您可以在查询中使用AsNoTracking方法。

var res = (from b in ctx.Buildings.Where(x => x.ID == 1)
         select new
         {
            b,
            flats = from f in b.Flats
                    select new
                    {
                       f,
                       people = from p in f.People
                       where p.Archived == false
                       select p
                    }
         }).AsNoTracking().AsEnumerabe().Select(x => x.b).Single();

我还想指出,你的AsEnumerable可能弊大于利。如果删除它,Select(x => x.b)将被转换为SQL。就是这样,你正在选择所有内容,然后扔掉除x.b之外的所有内容。

答案 1 :(得分:2)

你尝试过类似的事情吗?

ctx.Persons.Where(x => x.Flat.Building.Id == 1 && x.Archived == false);

=====编辑=====

在这种情况下,我认为你接近的是,imho,真的很危险。实际上,您处理由EF加载的数据来解释您的查询,而不是解释您的查询的数据。如果有一天EF更改是加载策略(例如预加载预测),您的方法将“将您送到墙上”。

为了您的目标,您必须急于加载构建“过滤”实体所需的数据。那就是选择建筑物,然后预选Flat选择非存档的人。

另一种解决方案是在“UnitOfWork”中使用过于单独的上下文,如设计。