EF Core中Logger类型转换异常:无法转换为IRelationalCommandDiagnosticsLogger
问题场景
执行EF Core LINQ查询时触发如下错误:
Unable to cast object of type 'Microsoft.EntityFrameworkCore.Diagnostics.Internal.DiagnosticsLogger`1[Microsoft.EntityFrameworkCore.DbLoggerCategory+Database+Command]' to type 'Microsoft.EntityFrameworkCore.Diagnostics.IRelationalCommandDiagnosticsLogger'
触发错误的代码:
await _myDbContext.SomeTableName.ToListAsync()
已知情况:
CanConnect()检查返回true- 可正常执行原始SQL查询
- 使用EF Core 6.0.20版本,项目依赖配置:
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.20" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.20" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.20" />
- Startup.cs中DbContext注册代码:
builder.Services.AddEntityFrameworkSqlServer(); builder.Services.AddDbContext<MyDBContext>((serviceProvider, optionsBuilder) => { optionsBuilder.UseSqlServer( configuration.GetValue<string>(ConfigurationConstants.CONNECTION_STRING), sqlServeroptionsBuilder => sqlServeroptionsBuilder.EnableRetryOnFailure()) .UseInternalServiceProvider(serviceProvider) .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); });
问题原因
错误源于注册DbContext时调用了.UseInternalServiceProvider(serviceProvider)。该方法会强制EF Core使用传入的服务提供者解析所有EF相关服务,但AddEntityFrameworkSqlServer()注册的关系型数据库专用诊断日志服务(IRelationalCommandDiagnosticsLogger)未被正确关联,导致EF尝试将通用DiagnosticsLogger转换为关系型专用日志接口时失败。
原始SQL查询和CanConnect()不受影响,是因为它们的执行逻辑不依赖该特定诊断日志接口。
解决方案
移除.UseInternalServiceProvider(serviceProvider)配置项即可,修改后的注册代码如下:
builder.Services.AddEntityFrameworkSqlServer(); builder.Services.AddDbContext<MyDBContext>((serviceProvider, optionsBuilder) => { optionsBuilder.UseSqlServer( configuration.GetValue<string>(ConfigurationConstants.CONNECTION_STRING), sqlServeroptionsBuilder => sqlServeroptionsBuilder.EnableRetryOnFailure()) .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); });
补充说明
如果业务场景确实需要手动指定服务提供者,需确保完整注册EF Core关系型数据库所需的所有服务(包括IRelationalCommandDiagnosticsLogger的实现)。但绝大多数场景下,无需手动调用UseInternalServiceProvider,AddDbContext会自动使用传入的serviceProvider解析所需服务,同时正确关联EF Core内置服务注册逻辑。
内容的提问来源于stack exchange,提问作者Mrityu

