使用简单注入器更新数据库,没有 services.AddDbContext<>()
Update-Database using Simple Injector, without services.AddDbContext<>()
.NET Core 3.1、EF Core 5.0 预览版 6.
我正在使用 Simple Injector 5.0 注册 IMyContextFactory
(我没有使用 services.AddDbContext<>()
)。
我的 MyContext
将所有构造函数设置为私有,因为我使用不带 tenantId 的 ContextFactory,有时在一个请求中使用几个不同的 tenantId,所以我确保每个人都会使用 IMyContextFactory
注入而不是 MyContext
并防止在控制器等中创建 new MyContext()
但是怎么办Update-Database
?
- 虽然我这样做
Update-Database
我总是有错误 Login failed for user ''.
,但我可以 运行 并从我的 WebAPI 项目连接到数据库没有任何问题(我的 ConnectionString 很好)。
- 我能够在 运行 时应用迁移,但我必须添加
services.AddDbContext<MyContext>()
,将 MyContext
的构造函数设为 public 并从 scope.ServiceProvider.GetRequiredService<MyContext>()
在 Program.cs,因为我的 IMyContextFactory
不在 ServiceProvider
里面。 (来自 https://docs.microsoft.com/pl-pl/ef/core/managing-schemas/migrations/applying?tabs=vs#apply-migrations-at-runtime)
如何仅使用 Simple Injector 实现?
解决方法是安装 Entity Framework Core .NET Command-line Tools 并从中更新数据库。
注意:在 Visual Studio 中禁用所有私有 NuGet 存储库并在程序包管理器控制台中安装工具:
dotnet tool install --global dotnet-ef --version 5.0.0-preview.6.20312.4
现在您可以在 Visual Studio 中启用您的私有 NuGet 源。
然后,转到您的上下文和配置所在的文件夹,然后:
dotnet ef database update --connection "Your=Connection;String"
您还可以使用 Update-Database
:
更改连接字符串
Update-Database -connection "Your=Connection;String"
但这是解决方法。我仍在向您寻求“内部”解决方案 Visual Studio IDE,无需安装额外的 CMD 工具
解决方案是将 ConnectionString 添加到您的 IDesignTimeDbContextFactory
实现中:
// Fix for "Unable to create an object of type 'MyContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728" error while creating migration
public class MyContextDesignFactory : IDesignTimeDbContextFactory<MyContext>
{
private string _appsettingsPath = "./../Path/To/ProjectWithAppsettingsJSON";
public MyContext CreateDbContext(string[] args)
{
// In 90% we don't have ASPNETCORE_ENVIRONMENT here, so set fallback to Development
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development";
var config = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), _appsettingsPath))
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{environment}.json", optional: true)
.Build();
Console.WriteLine($"Default ConnectionString comes from appsettings file.{Environment.NewLine}You can override it by using `dotnet ef database update --connection MyConnectionString`");
// Use ConnectionString from appsettings inside WebAPI to fix `Update-Database` command from Package Manager Console
// We still can override ConnectionString by `dotnet ef database update --connection MyConnectionString`
var optionsBuilder = new DbContextOptionsBuilder<MyContext>()
.UseSqlServer(config["ConnectionString"]);
return MyContext.MyContextFactory.GetMyContext(optionsBuilder.Options);
}
}
.NET Core 3.1、EF Core 5.0 预览版 6.
我正在使用 Simple Injector 5.0 注册 IMyContextFactory
(我没有使用 services.AddDbContext<>()
)。
我的 MyContext
将所有构造函数设置为私有,因为我使用不带 tenantId 的 ContextFactory,有时在一个请求中使用几个不同的 tenantId,所以我确保每个人都会使用 IMyContextFactory
注入而不是 MyContext
并防止在控制器等中创建 new MyContext()
但是怎么办Update-Database
?
- 虽然我这样做
Update-Database
我总是有错误Login failed for user ''.
,但我可以 运行 并从我的 WebAPI 项目连接到数据库没有任何问题(我的 ConnectionString 很好)。 - 我能够在 运行 时应用迁移,但我必须添加
services.AddDbContext<MyContext>()
,将MyContext
的构造函数设为 public 并从scope.ServiceProvider.GetRequiredService<MyContext>()
在 Program.cs,因为我的IMyContextFactory
不在ServiceProvider
里面。 (来自 https://docs.microsoft.com/pl-pl/ef/core/managing-schemas/migrations/applying?tabs=vs#apply-migrations-at-runtime)
如何仅使用 Simple Injector 实现?
解决方法是安装 Entity Framework Core .NET Command-line Tools 并从中更新数据库。
注意:在 Visual Studio 中禁用所有私有 NuGet 存储库并在程序包管理器控制台中安装工具:
dotnet tool install --global dotnet-ef --version 5.0.0-preview.6.20312.4
现在您可以在 Visual Studio 中启用您的私有 NuGet 源。
然后,转到您的上下文和配置所在的文件夹,然后:
dotnet ef database update --connection "Your=Connection;String"
您还可以使用 Update-Database
:
Update-Database -connection "Your=Connection;String"
但这是解决方法。我仍在向您寻求“内部”解决方案 Visual Studio IDE,无需安装额外的 CMD 工具
解决方案是将 ConnectionString 添加到您的 IDesignTimeDbContextFactory
实现中:
// Fix for "Unable to create an object of type 'MyContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728" error while creating migration
public class MyContextDesignFactory : IDesignTimeDbContextFactory<MyContext>
{
private string _appsettingsPath = "./../Path/To/ProjectWithAppsettingsJSON";
public MyContext CreateDbContext(string[] args)
{
// In 90% we don't have ASPNETCORE_ENVIRONMENT here, so set fallback to Development
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development";
var config = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), _appsettingsPath))
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{environment}.json", optional: true)
.Build();
Console.WriteLine($"Default ConnectionString comes from appsettings file.{Environment.NewLine}You can override it by using `dotnet ef database update --connection MyConnectionString`");
// Use ConnectionString from appsettings inside WebAPI to fix `Update-Database` command from Package Manager Console
// We still can override ConnectionString by `dotnet ef database update --connection MyConnectionString`
var optionsBuilder = new DbContextOptionsBuilder<MyContext>()
.UseSqlServer(config["ConnectionString"]);
return MyContext.MyContextFactory.GetMyContext(optionsBuilder.Options);
}
}