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

2024-01-07

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

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

System.InvalidOperationException:警告“Microsoft.EntityFrameworkCore.Infrastruct.ManyServiceProvidersCreatedWarning”生成错误:已创建了二十多个“IServiceProvider”实例供内部使用通过实体框架。这通常是由于将新的单例服务实例注入每个 DbContext 实例而引起的。例如,调用“UseLoggerFactory”每次都会传入一个新实例 - 请参阅https://go.microsoft.com/fwlink/?linkid=869049 https://go.microsoft.com/fwlink/?linkid=869049更多细节。这可能会导致性能问题,请考虑检查对“DbContextOptionsBuilder”的调用,这可能需要构建新的服务提供程序。通过将事件 ID“CoreEventId.ManyServiceProvidersCreatedWarning”传递给“DbContext.OnConfiguring”或“AddDbContext”中的“ConfigureWarnings”方法,可以抑制或记录此异常。

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

我已经阅读了存储库上的许多问题,并发现 EF 对各种事物进行了大量缓存,但关于该主题的文档不存在。建议是“找到导致这么多服务提供商被缓存的原因”,但我不知道要寻找什么。

那里有两个解决方法 https://github.com/dotnet/efcore/issues/16369:

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

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

我想知道的是:我有很多DbContext类型(因此IModel类型),影响服务提供商缓存?两者有关联吗? (我知道 EF 缓存IModel对于每一个DbContext,它是否还为每个提供者缓存一个服务提供者?)


服务提供者缓存纯粹基于上下文选项配置 - 上下文类型、模型等并不重要。

在 EF Core 5.0 中,密钥根据源代码 https://github.com/dotnet/efcore/blob/v5.0.13/src/EFCore/Internal/ServiceProviderCache.cs#L70 is

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 中您可以使用上述方法来检查密钥,在 6.0 中您可以使用一些静态字段来存储第一个选项实例并使用它来检查Equals下一个)。

请注意,EF Core 会缓存原始数据和之后的数据OnConfiguring看涨期权,所以它们都很重要。顺便说一句,生成警告的代码位于同一位置(类) -source https://github.com/dotnet/efcore/blob/v5.0.13/src/EFCore/Internal/ServiceProviderCache.cs#L153.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

测试期间的 EF Core 内部缓存和许多 DbContext 类型 的相关文章

  • ROWNUM 的 OracleType 是什么

    我试图参数化所有现有的 sql 但以下代码给了我一个问题 command CommandText String Format SELECT FROM 0 WHERE ROWNUM lt maxRecords command CommandT
  • 在 LINQ 查询中返回不带时间的日期

    我正在编写一个查询 我想计算按日期联系我们的呼叫中心的次数 看起来很简单 但由于联系日期字段是日期时间字段 我得到了时间 因此当我按联系日期 时间 分组时 每个联系日期实例的计数为 1 所以 我想只按日期分组 而不按时间分组 下面是我用来查
  • 自动从 C# 代码进行调试过程并读取寄存器值

    我正在寻找一种方法来读取某个地址的 edx 注册表 就像这个问题中所问的那样 读取eax寄存器 https stackoverflow com questions 16490906 read eax register 虽然我的解决方案需要用
  • SSH 主机密钥指纹与模式 C# WinSCP 不匹配

    我尝试通过 WinSCP 使用 C 连接到 FTPS 服务器 但收到此错误 SSH 主机密钥指纹 与模式不匹配 经过大量研究 我相信这与密钥的长度有关 当使用 服务器和协议信息 下的界面进行连接时 我从 WinSCP 获得的密钥是xx xx
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • 为什么 POSIX 允许在只读模式下超出现有文件结尾 (fseek) 进行搜索

    为什么寻找文件结尾很有用 为什么 POSIX 让我们像示例中那样在以只读方式打开的文件中进行查找 c http en cppreference com w c io fseek http en cppreference com w c io
  • 使用 Google Analytics API 在 C# 中显示信息

    我一整天都在寻找一个好的解决方案 但谷歌发展得太快了 我找不到有效的解决方案 我想做的是 我有一个 Web 应用程序 它有一个管理部分 用户需要登录才能查看信息 在本节中 我想显示来自 GA 的一些数据 例如某些特定网址的综合浏览量 因为我
  • HttpClient 像浏览器一样请求

    当我通过 HttpClient 类调用网站 www livescore com 时 我总是收到错误 500 可能服务器阻止了来自 HttpClient 的请求 1 还有其他方法可以从网页获取html吗 2 如何设置标题来获取html内容 当
  • 基于范围的 for 循环中的未命名循环变量?

    有没有什么方法可以不在基于范围的 for 循环中 使用 循环变量 同时也避免编译器发出有关未使用它的警告 对于上下文 我正在尝试执行以下操作 我启用了 将警告视为错误 并且我不想进行像通过在某处毫无意义地提及变量来强制 使用 变量这样的黑客
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • Windows 窗体不会在调试模式下显示

    我最近升级到 VS 2012 我有一组在 VS 2010 中编码的 UI 测试 我试图在 VS 2012 中启动它们 我有一个 Windows 窗体 在开始时显示使用 AssemblyInitialize 属性运行测试 我使用此表单允许用户
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • 如何在android sdk上使用PowerMock

    我想为我的 android 项目编写一些单元测试和仪器测试 然而 我遇到了一个困扰我一段时间的问题 我需要模拟静态方法并伪造返回值来测试项目 经过一些论坛的调查 唯一的方法是使用PowerMock来模拟静态方法 这是我的 gradle 的一
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 在Linux中使用C/C++获取机器序列号和CPU ID

    在Linux系统中如何获取机器序列号和CPU ID 示例代码受到高度赞赏 Here http lxr linux no linux v2 6 39 arch x86 include asm processor h L173Linux 内核似
  • Bing 地图运行时错误 Windows 8.1

    当我运行带有 Bing Map 集成的 Windows 8 1 应用程序时 出现以下错误 Windows UI Xaml Markup XamlParseException 类型的异常 发生在 DistanceApp exe 中 但未在用户
  • 将变量分配给另一个变量,并将一个变量的更改反映到另一个变量中

    是否可以将一个变量分配给另一个变量 并且当您更改第二个变量时 更改会瀑布式下降到第一个变量 像这样 int a 0 int b a b 1 现在 b 和 a 都 1 我问这个问题的原因是因为我有 4 个要跟踪的对象 并且我使用名为 curr
  • 将 viewbag 从操作控制器传递到部分视图

    我有一个带有部分视图的 mvc 视图 控制器中有一个 ActionResult 方法 它将返回 PartialView 因此 我需要将 ViewBag 数据从 ActionResult 方法传递到 Partial View 这是我的控制器
  • 为什么 strtok 会导致分段错误?

    为什么下面的代码给出了Seg 最后一行有问题吗 char m ReadName printf nRead String s n m Writes OK char token token strtok m 如前所述 读取字符串打印没有问题 但

随机推荐