EF是否在DbContext的不同实例之间缓存实体?

mró*_*ówa 7 .net asp.net entity-framework dbcontext asp.net-mvc-4

在Asp.net中为每个查询创建DbContext是否只使EF从其缓存中读取数据,或者每次都查询整个集合中的数据?我知道每个AppDomain的元数据缓存,但只是数据呢?

上下文:使用MVC4 + Web API前端的数据采集和可视化应用程序不会称之为"高容量",但是许多查询在较短的时间范围内返回相同的数据集.

Sla*_*uma 14

实体框架每个AppDomain没有数据缓存,每个上下文实例只有一个缓存.

如果为每个请求或查询创建新上下文,则从空缓存开始,EF将从数据库中获取数据.

此外,术语"每个上下文实例的缓存"可能会产生误导,因为它并不意味着如果实体已经加载到上下文缓存中,EF将不会对数据库运行查询.此缓存的工作方式以及如何利用它(或不使用)如下:

  • 一个LINQ到实体查询DbSet<T>或一般上IQueryable<T>,如果实体已经存在于环境或不运行数据库查询,不管.但是,如果在上下文中存在与查询实体具有相同密钥的实体,EF将抛出该查询的结果并将缓存的实体实例返回给调用者.

    它会检查运行查询是否存在具有相同密钥的实体.(对于复杂查询 - 例如包含的查询 - Include之前无法执行此检查,因为它无法知道将返回哪些实体和键值.)

    这是默认行为(MergeOptionAppendOnly).OverwriteChanges我相信您可以将此行为更改为其他选项,但它们都不会避免LINQ查询始终发出数据库查询.

  • 对于仅通过其键查询实体,您可以使用GetObjectByKeyFind(with DbContext)首先检查具有该键的实体是否已在上下文中缓存,然后返回此缓存对象.如果不是,它将运行数据库查询来加载它.

  • 您可以查询EF的ChangeTracker,它特别受到DbContext您通过DbSet<T>.Local集合访问上下文缓存的支持.

    这里的问题是,如果查询Local不返回结果,则没有逻辑可以自动查询数据库.你必须手动编写这个逻辑.更大的问题是查询Local是LINQ到对象而不是LINQ到实体(仅仅Local是实现),因此您经常需要重写查询以执行操作- 例如您无法使用在这里,你不能使用任何,你将获得有关区分大小写等的字符串比较等不同的行为.IQueryable<T>IEnumerable<T>LocalIncludeEntityFunctions