在同一项目中同时使用AddDbContextFactory()和AddDbContext()扩展方法
c#
我正在尝试使用EF Core 文档的 DbContext 配置部分中DbContextFactory讨论的新模式。
我已经DbContextFactory在我的 Blazor 应用程序中成功启动并运行,但我想保留DbContext直接注入实例的选项,以保持我现有的代码正常工作。
但是,当我尝试这样做时,出现以下错误:
System.AggregateException:无法构造某些服务(验证服务描述符“ServiceType: Microsoft.EntityFrameworkCore.IDbContextFactory
1[MyContext] Lifetime: Singleton ImplementationType: Microsoft.EntityFrameworkCore.Internal.DbContextFactory1[MyContext]”时出错:无法使用范围服务“Microsoft.EntityFrameworkCore.DbContextOptions1[MyContext]' from singleton 'Microsoft.EntityFrameworkCore.IDbContextFactory1[MyContext]”。) ---> System.InvalidOperationException:验证服务描述符“ServiceType:Microsoft.EntityFrameworkCore.IDbContextFactory1[MyContext] Lifetime: Singleton ImplementationType: Microsoft.EntityFrameworkCore.Internal.DbContextFactory1[MyContext]”时出错:无法使用范围服务“Microsoft.EntityFrameworkCore.DbContextOptions1[MyContext]' from singleton 'Microsoft.EntityFrameworkCore.IDbContextFactory1[MyContext]”。---> System.InvalidOperationException:无法使用范围服务“Microsoft.EntityFrameworkCore.DbContextOptions1[MyContext]' from singleton 'Microsoft.EntityFrameworkCore.IDbContextFactory1[MyContext]”。
在试验时,我还设法在某一时刻得到了这个错误:
无法从根提供程序解析范围服务“Microsoft.EntityFrameworkCore.DbContextOptions`1[MyContext]”。
它是理论上可以同时使用AddDbContext和AddDbContextFactory在一起?
回答
是的,这完全是关于了解游戏中各种元素的生命周期并正确设置它们。
默认情况下,DbContextFactory由AddDbContextFactory()扩展方法创建的具有单例生命周期。如果您使用AddDbContext()带有默认设置的扩展方法,它将创建一个DbContextOptions具有Scoped生命周期的对象(请参阅此处的源代码),并且由于Singleton不能使用Scoped生命周期较短的东西,因此会引发错误。
为了解决这个问题,我们需要将 的生命周期DbContextOptions也改为“单例”。这可以通过显式设置DbContextOptions参数的范围来完成AddDbContext()
services.AddDbContext<FusionContext>(options =>
options.UseSqlServer(YourSqlConnection),
contextLifetime: ServiceLifetime.Transient,
optionsLifetime: ServiceLifetime.Singleton);
从这里开始的 EF 核心 GitHub 存储库上对此进行了非常好的讨论。也值得一看DbContextFactory 这里的源代码。
或者,您还可以DbContextFactory通过在构造函数中设置 ServiceLifetime 参数来更改 的生命周期:
services.AddDbContextFactory<FusionContext>(options =>
options.UseSqlServer(YourSqlConnection),
ServiceLifetime.Scoped);
这些选项的配置应与普通 DbContext完全一样,因为这些选项将在工厂创建的 DbContext 上设置。
- This answer is very useful to people who are upgrading to .NET 5 and are looking to use Blazor and MVC Core in the same project, although I do not know what ApplyOurOptions is. If that isn't a part of EF that I'm unaware of, perhaps consider converting this to use normal options?