Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework DbContext缓存数据_Entity Framework_Entity Framework 6 - Fatal编程技术网

Entity framework DbContext缓存数据

Entity framework DbContext缓存数据,entity-framework,entity-framework-6,Entity Framework,Entity Framework 6,我到处都读到,从数据库获取新数据的正确方法是创建DbContext的新实例,并删除现有的。虽然在某些场景中这可能是不可能的,但我发现在更复杂的场景中实现这一点很困难。所讨论的应用程序类型是客户端应用程序,只要显示表单/视图,上下文就一直存在 例如,假设我们正在添加一些类型A的数据,这是主数据,类型A的特定实例引用类型B和C的对象,这是引用的数据。这意味着在屏幕上我可以加载A列表、B列表和C列表。假设B列表在网络上收到了一些更改,我想加载这些更改。我如何刷新B的列表,而不需要从数据库中获取所有三个

我到处都读到,从数据库获取新数据的正确方法是创建DbContext的新实例,并删除现有的。虽然在某些场景中这可能是不可能的,但我发现在更复杂的场景中实现这一点很困难。所讨论的应用程序类型是客户端应用程序,只要显示表单/视图,上下文就一直存在

例如,假设我们正在添加一些类型A的数据,这是主数据,类型A的特定实例引用类型B和C的对象,这是引用的数据。这意味着在屏幕上我可以加载A列表、B列表和C列表。假设B列表在网络上收到了一些更改,我想加载这些更改。我如何刷新B的列表,而不需要从数据库中获取所有三个列表,因为如果我破坏了上下文,我将需要这样做

obvoius mehod会像

Context.Set<B>().AsNoCache().ToList();

我们没有…

您正在寻找的方法是


你要找的方法是


如果要使用数据库中可能更新的值更新现有实体列表,可以使用ObjectContext的方法:


注意:如果列表中添加了项目,则不会从数据库加载新实体-您需要重新查询这些项目。

如果您希望使用数据库中可能更新的值更新现有实体列表,可以使用ObjectContext的方法:


注意:如果列表中添加了项目,则不会从数据库中加载新实体-您需要重新查询这些项目。

在测试期间,我发现使用数据库中的当前记录刷新数据的唯一方法是,更新和删除是使用ObjectContext的ObjectSet和set MergeOption覆盖更改DbContext不公开这样的方法

var objectContext = ((IObjectContextAdapter)Context).ObjectContext;
ObjectSet<T> set = objectContext.CreateObjectSet<T>();
set.MergeOption = MergeOption.OverwriteChanges;
var list = set.ToList();

在测试过程中,我发现使用添加、更新和删除的数据库中的当前记录刷新数据的唯一方法是使用ObjectContext的ObjectSet和set MergeOption覆盖更改DbContext,而不是公开这样的方法

var objectContext = ((IObjectContextAdapter)Context).ObjectContext;
ObjectSet<T> set = objectContext.CreateObjectSet<T>();
set.MergeOption = MergeOption.OverwriteChanges;
var list = set.ToList();

我不知道在上面的场景中如何使用AsNoTracking,但也许我没有看到什么。如果我没有跟踪某个东西,这意味着它没有附加到上下文。如果未附加到上下文,则无法更新。在上面的场景中,我正在更新数据。那么,你到底是如何做到这一点的呢?@Goran你可以附加未被跟踪的实体。你甚至可以把一个实体附加到一个不同的上下文中去,我知道我可以附加它。如果我访问它,那么它将被缓存。我将如何更新它,因为现在它正在被跟踪,这与您所建议的情况相反?我认为诀窍是不要有一个长期存在的上下文。加载数据并关闭上下文。进行更改后,您可以创建新的上下文实例、附加、保存和关闭。建议web应用使用您正在讨论的场景。对于客户端apss,建议其上下文生命周期与视图/表单生命周期相同。想象一下,如果我需要加载8个不同的集合,这是我当前的场景,在每个导航上-不是最好的性能…我不知道如何在上面的场景中使用AsNoTracking,但也许我没有看到什么。如果我没有跟踪某个东西,这意味着它没有附加到上下文。如果未附加到上下文,则无法更新。在上面的场景中,我正在更新数据。那么,你到底是如何做到这一点的呢?@Goran你可以附加未被跟踪的实体。你甚至可以把一个实体附加到一个不同的上下文中去,我知道我可以附加它。如果我访问它,那么它将被缓存。我将如何更新它,因为现在它正在被跟踪,这与您所建议的情况相反?我认为诀窍是不要有一个长期存在的上下文。加载数据并关闭上下文。进行更改后,您可以创建新的上下文实例、附加、保存和关闭。建议web应用使用您正在讨论的场景。对于客户端apss,建议其上下文生命周期与视图/表单生命周期相同。想象一下,如果我需要在每个导航上加载8个不同的集合,这是我当前的场景,而不是最佳性能…这是我在处理单个实体列表时使用的方法。但是,我看不到更新对象图数据的方法?想象一下,在上面的场景中,a是发票,B是发票项,C是产品,D是客户,等等。如果发票123在网络上发生了更改,并且我正在通过发票来回导航,那么当我导航到发票123时,我将如何加载新数据?从您希望刷新的对象图中创建实体列表,假设我点击后退按钮加载上一条记录。此时,我不知道以前的记录是什么,因此我需要从数据库中获取它,以便获得添加的项。
然后我会检查上下文是否缓存了它。如果是的话,那么我会制作三个列表,每个列表分别对应于父实体、子实体和孙辈,并将它们发送给刷新。这就是你的建议,我需要确保在做一些测试之前我理解了。这是我在处理单实体列表时使用的方法。但是,我看不到更新对象图数据的方法?想象一下,在上面的场景中,a是发票,B是发票项,C是产品,D是客户,等等。如果发票123在网络上发生了更改,并且我正在通过发票来回导航,那么当我导航到发票123时,我将如何加载新数据?从您希望刷新的对象图中创建实体列表,假设我点击后退按钮加载上一条记录。此时,我不知道以前的记录是什么,因此我需要从数据库中获取它,以便获得添加的项。然后我会检查上下文是否缓存了它。如果是的话,那么我会制作三个列表,每个列表分别对应于父实体、子实体和孙辈,并将它们发送给刷新。这就是你的建议,我需要确保在做一些测试之前我理解了。
var objectContext = ((IObjectContextAdapter)Context).ObjectContext;
ObjectSet<T> set = objectContext.CreateObjectSet<T>();
set.MergeOption = MergeOption.OverwriteChanges;
var list = set.ToList();