gpt4 book ai didi

c# - 测试期间的 EF Core 内部缓存和许多 DbContext 类型

转载 作者:行者123 更新时间:2023-12-05 02:35:35 24 4
gpt4 key购买 nike

我有很多测试类,每个类都有几十个测试。我想隔离测试,所以不用大型上下文 MyDbContext , 我用 MyDbContextToTestFoo , MyDbContextToTestBar , MyDbContextToTestBaz等所以我有很多 DbContext子类。

在我使用 EF Core 5 进行的单元测试中,我遇到了 ManyServiceProvidersCreatedWarning .它们单独工作,但许多在作为一个组运行时会失败:

System.InvalidOperationException : An error was generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.ManyServiceProvidersCreatedWarning': More than twenty 'IServiceProvider' instances have been created for internal use by Entity Framework. This is commonly caused by injection of a new singleton service instance into every DbContext instance. For example, calling 'UseLoggerFactory' passing in a new instance each time--see https://go.microsoft.com/fwlink/?linkid=869049 for more details. This may lead to performance issues, consider reviewing calls on 'DbContextOptionsBuilder' that may require new service providers to be built. This exception can be suppressed or logged by passing event ID 'CoreEventId.ManyServiceProvidersCreatedWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.

我不会对 DbContextOptionsBuilder 做任何奇怪的事情正如该错误所暗示的那样。我不知道如何诊断“......可能需要建立新的服务提供商”。在大多数测试中,我通常会创建一个上下文:new DbContextOptionsBuilder<TContext>().UseSqlite("DataSource=:memory:")其中 TContext是我上面提到的上下文类型之一。

我已经阅读了关于 repo 的许多问题,并发现 EF 对各种事物进行了大量缓存,但是关于该主题的文档不存在。推荐是“查找导致这么多服务提供者被缓存的原因”,但我不知道该查找什么。

有两个workarounds :

  • builder.EnableServiceProviderCaching(false)这显然对性能非常不利
  • builder.ConfigureWarnings(x => x.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))这忽略了问题

我假设“服务提供者”是指 EF 的内部 IoC 容器。

我想知道的是:事实上我有很多 DbContext类型(以及 IModel 类型),影响服务提供商缓存?两者有关系吗? (我知道 EF 为每个 IModel 缓存一个 DbContext,它是否也为每个缓存一个服务提供者?)

最佳答案

服务提供商缓存完全基于上下文选项配置 - 上下文类型、模型等无关紧要。

在 EF Core 5.0 中, key 根据 source code

static long GetCacheKey(IDbContextOptions options) => options.Extensions
.OrderBy(e => e.GetType().Name)
.Aggregate(0L, (t, e) => (t * 397) ^ ((long)e.GetType().GetHashCode() * 397) ^ e.Info.GetServiceProviderHashCode());

而在 EF Core 6.0 中,关键是具有类似语义的重写 Equals 方法的选项实例。

所以您使用的选项有所不同 - 如果您正在覆盖它并修改其中的选项,则在最初或 OnConfiguring 调用之后。这是你需要弄清楚的(在 5.0 中你可以使用上面的方法来检查 key ,在 6.0 中你可以使用一些静态字段来存储第一个选项实例并使用它来检查 Equals下一个)。

请注意,EF Core 缓存原始和之后的 OnConfiguring 调用选项,因此它们都算在内。顺便说一句,生成警告的代码在同一个地方(类)- source .

关于c# - 测试期间的 EF Core 内部缓存和许多 DbContext 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70503024/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com