Asp.net EF是否在DbContext的不同实例之间缓存实体?
在Asp.net中创建每个查询的DbContext是使EF只从其缓存中读取数据,还是每次都查询整个集合的数据库?我知道每个AppDomain都有元数据缓存,但仅仅是数据呢Asp.net EF是否在DbContext的不同实例之间缓存实体?,asp.net,.net,entity-framework,asp.net-mvc-4,dbcontext,Asp.net,.net,Entity Framework,Asp.net Mvc 4,Dbcontext,在Asp.net中创建每个查询的DbContext是使EF只从其缓存中读取数据,还是每次都查询整个集合的数据库?我知道每个AppDomain都有元数据缓存,但仅仅是数据呢 上下文:使用MVC4+Web API前端的数据采集和可视化应用程序不会称之为“高容量”,但许多查询会在较短的时间内返回相同的数据集。实体框架没有每个AppDomain的数据缓存,只有每个上下文实例的缓存 如果您为每个请求或查询创建一个新的上下文,则从一个空缓存开始,EF将从数据库中获取数据 此外,术语“每个上下文实例的缓存”可
上下文:使用MVC4+Web API前端的数据采集和可视化应用程序不会称之为“高容量”,但许多查询会在较短的时间内返回相同的数据集。实体框架没有每个AppDomain的数据缓存,只有每个上下文实例的缓存 如果您为每个请求或查询创建一个新的上下文,则从一个空缓存开始,EF将从数据库中获取数据 此外,术语“每个上下文实例的缓存”可能会产生误导,因为这并不意味着如果实体已经加载到上下文缓存中,EF不会对数据库运行查询。此缓存的工作方式以及您可以(或不可以)利用它的方式如下:
- 在
或通常在DbSet
上的每个LINQ to Entities查询都将运行数据库查询,无论上下文中是否已经存在实体。但是,如果上下文中已经存在与查询实体具有相同键的实体,EF将丢弃该查询的结果,并将缓存的实体实例返回给调用者 它在运行查询后检查是否存在具有相同键的实体。(对于复杂的查询(例如,包含IQueryable
的查询),它以前不能执行此检查,因为它不知道将返回哪些实体和键值。) 这是默认行为(Include
是MergeOption
)。我相信,您可以将此行为更改为AppendOnly
和其他选项,但它们都无法避免LINQ查询总是发出数据库查询OverwriteChanges
- 对于仅通过其键查询实体,您可以使用
或GetObjectByKey
(使用Find
)首先检查具有该键的实体是否已缓存在上下文中,然后返回该缓存对象。如果没有,它将运行数据库查询来加载它DbContext
- 您可以查询EF的ChangeTracker,它在
中尤其受支持,您可以通过DbContext
集合访问上下文缓存 这里的问题是,如果对DbSet.Local
的查询没有返回结果,则没有逻辑自动查询数据库。您必须手动编写此逻辑。更大的问题是对Local
的查询是对对象的LINQ,而不是对实体的LINQ(Local
不实现Local
,只实现IQueryable
),因此您经常必须重写查询以对IEnumerable
执行操作-例如,您不能在此处使用Local
,您不能使用任何Include
,在区分大小写等方面,您将获得不同的字符串比较行为EntityFunctions