本文介绍了EF DbContext。如何避免缓存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

花了很多时间,但是仍然不明白如何避免在DbContext中进行缓存。



我在下面的一些简单案例的实体模型上附加了演示内容



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

 使用(TestContext ctx = new TestContext())
{
var res =(从ctx.Buildings.Where(x => x.ID == 1)中的b)
选择新的
{
b,
单位=从b中的f开始单位
选择新的
{
f,
人=从f中的p人
其中p。已存档==假
select p
}
})。AsEnumerable()。Select(x => xb).Single();

}

在这种情况下,一切都很好:我得到了我所得到的



但是,如果我在其后添加另一个查询,则查询建筑物中已将已存档标志设置为是的,我有接下来的事情,我真的无法理解:


  1. 我之前的结果,即 res ,将按数据添加(还会添加
    ,也将添加已存档== true的人员)

  2. 新结果将包含所有人员的绝对值,无论存档等于什么

此查询的代码如下:

 使用(TestContext ctx = new TestContext())
{
var res =(来自ctx.Buildings.W中的b,其中(x => x.ID == 1)
选择新的
{
b,
单位=从b中的f开始
选择新的
{
f,
人=来自f中的p人
,其中p.Archived ==假
select p
}
})。AsEnumerable()。Select(x => x.b).Single();


var newResult =(来自ctx.Buildings.Where(x => x.ID == 1)中的b)
选择新的
{
b,
单位=来自b中的f。单位
选择新的
{
f,
人=来自f中的p人
其中p。已归档== true
select p
}
})。AsEnumerable()。Select(x => xb).Single();
}

顺便说一句,我将 LazyLoadingEnabled 设置为false



有人知道如何解决此问题吗?我如何在查询中得到我在linq中真正写给实体的东西?



P.S。 @ p。

解决方案

您可以使用方法。

  var res =(从ctx.Buildings.Where中的b开始(x => x.ID == 1)
选择新的
{
b,
单位=从b中的f
选择新的
{
f,
人=来自f中的p人
其中p。已存档==假
选择p
}
})。AsNoTracking()。AsEnumerabe()。Select(x => xb).Single();

我还想指出,您的 AsEnumerable 弊大于利。如果删除它, Select(x => x.b)将被转换为SQL。照原样,您正在选择所有内容,然后丢弃内存中除 x.b 之外的所有内容。


Spent a lot of time, but still cann't understand how to avoid caching in DbContext.

I attached below entity model of some easy case to demonstrate what I mean.

The problem is that dbcontext caching results. For example, I have next code for querying data from my database:

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();

}

In this case, everything is fine: I got what I want (Only persons with Archived == false).

But if I add another query after it, for example, query for buildings that have people that have Archived flag set to true, I have next things, that I really cann't understand:

  1. my previous result, that is res, will be added by data (therewill be added Persons with Archived == true too)
  2. new result will contain absolutely all Person's, no matter what Archived equals

the code of this query is next:

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();
            }

By the way, I set LazyLoadingEnabled to false in constructor of TestContext.

Does anybody know how to workaround this problem? How can I have in my query what I really write in my linq to entity?

P.S. @Ladislav may be you can help?

解决方案

You can use the AsNoTracking method on your query.

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();

I also want to note that your AsEnumerable is probably doing more harm than good. If you remove it, the Select(x => x.b) will be translated to SQL. As is, you are selecting everything, then throwing away everything but x.b in memory.

这篇关于EF DbContext。如何避免缓存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 01:16