Rez*_*oei 5 c# docker entity-framework-core asp.net-core-webapi entity-framework-migrations
我已在 Docker 上部署了 ASP.NET Core Web API。我的应用程序还与 Docker 容器中的 SQL Server 交互。
这是我的docker-compose.yml文件:
version: '3'
services:
db:
image: mcr.microsoft.com/mssql/server
container_name: db
ports:
- 1533:1433
environment:
- TZ=Asia/Tehran
- ACCEPT_EULA=Y
- MSSQL_SA_PASSWORD=******
user: root
volumes:
- ./mssql:/var/opt/mssql/data
kava-service:
image: service:1.0.0
container_name: service
expose:
- 9001
ports:
- 9001:9001
depends_on:
- db
environment:
- ASPNETCORE__ENVIRONMENT=Production
- TZ=Asia/Tehran
- AUTO__MIGRATE=true
- ConnectionStrings__BusinessDomainConnectionString=Server=db;Initial Catalog=Kava.BusinessDomain;User ID=sa;pwd=****;MultipleActiveResultSets=true;
- ConnectionStrings__RecordsConnectionString=Server=db;Initial Catalog=Kava.Records;User Id=sa;pwd=****;MultipleActiveResultSets=true;
Run Code Online (Sandbox Code Playgroud)
当我运行 docker 容器(使用docker-compose)时,它工作正常。但是,如果我重新启动此容器,它就不起作用,并且应用程序将退出并显示以下消息:
用户“sa”登录失败。原因:无法打开显式指定的数据库“Kava.BusinessDomain”[客户端:172.18.0.4] kava-service
未处理的异常。Microsoft.Data.SqlClient.SqlException(0x80131904):数据库“Kava.BusinessDomain”已存在。选择不同的数据库名称。
当我删除这个数据库时,一切正常,但我不想删除它。
在开发中(我的意思是 Visual Studio)一切都很好,但在生产中(Docker),迁移无法按预期进行。
这是我的迁移命令:
BusinessDomainContext businessDomainContext = serviceScope.ServiceProvider.GetRequiredService<IBusinessDomainDatabaseFactory>().Get() as BusinessDomainContext;
await businessDomainContext.Database.MigrateAsync();
Run Code Online (Sandbox Code Playgroud)
您的迁移过程可能会尝试创建一个已经存在的数据库。您的ASP.NET Core应用程序应检查数据库是否存在,并仅应用必要的迁移,而不是每次都尝试创建新数据库(使用“在应用程序启动时解析服务”)。
using (var scope = app.ApplicationServices.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<BusinessDomainContext>();
// Check if the database exists and apply migrations if necessary
if (context.Database.CanConnect())
{
// context.Database.GetPendingMigrations().Any() is another option.
if (!context.Database.GetAppliedMigrations().SequenceEqual(context.Database.GetMigrations()))
{
await context.Database.MigrateAsync();
}
}
else
{
// Logic to handle the scenario where the database does not exist
// That might include creating the database, if that is your intention
}
}
Run Code Online (Sandbox Code Playgroud)
该Login failed for user 'sa'错误可能是应用程序尝试连接时 SQL Server 容器未完全准备就绪的症状。您可以使用连接字符串测试数据库连接重试策略的实现,如“实现弹性 Entity Framework Core SQL 连接”中所示。
services.AddDbContext<BusinessDomainContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("BusinessDomainConnectionString"),
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.EnableRetryOnFailure(
maxRetryCount: 5,
maxRetryDelay: TimeSpan.FromSeconds(10),
errorNumbersToAdd: null);
}));
Run Code Online (Sandbox Code Playgroud)
这将设置一个重试策略,应用程序将尝试重新连接到数据库最多五次,重试之间有 10 秒的延迟。
此外,出于调试目的,请尝试增强这些操作的日志记录。并使用docker-compose up -d; docker-compose logs -fto 在后台运行服务,然后跟踪容器的任何输出。
在应用程序内部,您可以使用日志框架来记录消息。在 ASP.NET Core 应用程序中,您可以使用内置的日志记录框架。您可以在您的Program.cs或Startup.cs文件中将其配置为将消息记录到控制台,然后 Docker 将获取这些消息。
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
});
Run Code Online (Sandbox Code Playgroud)
您可以将ASPNETCORE_ENVIRONMENT环境变量设置为Development从 ASP.NET Core 应用程序获取更详细的日志。
可以在您的docker-compose.yml文件中使用command服务字段来覆盖 Docker 映像在容器启动时运行的默认命令来完成此操作。
这对于添加标志或参数以启用更详细的日志记录非常有用。
例如,如果您的应用程序接受一个--verbose标志来启用更详细的日志,您可以添加command如下字段:
services:
service:
image: service:1.0.0
command: ["./your-app", "--verbose"]
# rest of your service configuration
Run Code Online (Sandbox Code Playgroud)
在 ASP.NET Core 应用程序的上下文中,您可以使用环境变量控制日志级别。例如,您可以设置或Logging__LogLevel__DefaultDebug获取Information更详细的日志:
services:
service:
image: service:1.0.0
environment:
- ASPNETCORE__ENVIRONMENT=Development
- AzureFunctionsJobHost__logging__logLevel__default=Debug
# rest of your service configuration
Run Code Online (Sandbox Code Playgroud)
Debug这会将应用程序中所有类别的日志的日志级别设置为。您还可以使用环境变量(例如Logging__LogLevel__Microsoft=Information.
| 归档时间: |
|
| 查看次数: |
231 次 |
| 最近记录: |