Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有多个数据库上下文的.NET Core应用程序不会在所有数据库上下文中生成表_C#_Mysql_.net Core_Web Deployment - Fatal编程技术网

C# 具有多个数据库上下文的.NET Core应用程序不会在所有数据库上下文中生成表

C# 具有多个数据库上下文的.NET Core应用程序不会在所有数据库上下文中生成表,c#,mysql,.net-core,web-deployment,C#,Mysql,.net Core,Web Deployment,我已经用.NETCore3.1制作了一个OData服务器 在这个应用程序中,我有两个数据库上下文。其中一个用于应用程序本身(AppDbContext),另一个用于帐户管理和身份验证(AccountDbContext)。 我有一个ServiceExtensions如下: 公共静态类服务扩展 { 公共静态void配置mysqlcontext(此IServiceCollection服务,IConfiguration配置) { services.AddDbContext(选项=> { options.U

我已经用
.NETCore3.1
制作了一个OData服务器

在这个应用程序中,我有两个数据库上下文。其中一个用于应用程序本身(AppDbContext),另一个用于帐户管理和身份验证(AccountDbContext)。

我有一个
ServiceExtensions
如下:

公共静态类服务扩展
{
公共静态void配置mysqlcontext(此IServiceCollection服务,IConfiguration配置)
{
services.AddDbContext(选项=>
{
options.UseMySql(configuration.GetConnectionString(“MysqlConnection”),
mysqlOptions=>{
ServerVersion(新的ServerVersion(新的版本(5,4,3),ServerType.MySql));
});
});
services.AddDbContext(选项=>
{
options.UseMySql(configuration.GetConnectionString(“MysqlConnection”),
mysqlOptions=>{
ServerVersion(新的ServerVersion(新的版本(5,4,3),ServerType.MySql));
});
});
}
}
startup.cs
中,我将调用
ConfigureMySqlContext
函数,如下所示:


公营创业
{
公共启动(IConfiguration配置)
{
配置=配置;
}
公共IConfiguration配置{get;}
//此方法由运行时调用。
//我使用此方法将服务添加到容器中。
public void配置服务(IServiceCollection服务)
{
services.ConfigureMySqlContext(配置);
}
}
公共静态类程序
{
公共静态void Main(字符串[]args)
{
CreateWebHostBuilder(args)
.Build()
.CreateDbIfNotExists()文件
.Run();
}
专用静态IHost CreateDbIfNotExists(此IHost主机)
{
使用(var scope=host.Services.CreateScope())
{
var services=scope.ServiceProvider;
var accountDbContext=services.GetRequiredService();
accountDbContext.Database.Recreated();
var appDbContext=services.GetRequiredService();
appDbContext.Database.recreated();
}
返回主机;
}
}
这段代码的目的是在数据库中的两个上下文中生成所需的表。 问题是,当我将此应用程序发布到服务器时,当应用程序第一次运行时,它只会生成并启动
AppDbContext
中的表。为什么?因为它位于
AccountDbContext
之前

如果我更改
ConfigureMySqlContext
功能如下,然后再次发布应用程序:

公共静态类服务扩展
{
公共静态void配置mysqlcontext(此IServiceCollection服务,IConfiguration配置)
{
services.AddDbContext(选项=>
{
options.UseMySql(configuration.GetConnectionString(“MysqlConnection”),
mysqlOptions=>{
ServerVersion(新的ServerVersion(新的版本(5,4,3),ServerType.MySql));
});
});
services.AddDbContext(选项=>
{
options.UseMySql(configuration.GetConnectionString(“MysqlConnection”),
mysqlOptions=>{
ServerVersion(新的ServerVersion(新的版本(5,4,3),ServerType.MySql));
});
});       
}        
}

然后将是
AccountDbContext
中的表,第一次运行后将在数据库中启动这些表。

问题是,在其核心,
重新创建的
具有非常简单的语义,可以建模为:

如果(!database.exists()){
create();
}
其中
exists()
检查数据库是否存在,而不检查数据库中的表是否存在

其最终结果是,如果数据库不是完全空的,
EnsureCreated()
将无效

解决这个问题有两种方法:

  • 将数据库分成两部分。这是EntityFramework最喜欢的解决方案
  • 但是,如果这不是一个选项,请查看:

  • 查看
    IRelationalDatabaseCreator.CreateTables()
    方法:
  • 以下是一个可能的解决方案:

    使用Microsoft.EntityFrameworkCore.Storage;
    使用Microsoft.EntityFrameworkCore.Infrastructure;
    公共静态类程序
    {
    公共静态void Main(字符串[]args)
    {
    CreateWebHostBuilder(args)
    .Build()
    .CreateDbIfNotExists()文件
    .Run();
    }
    专用静态IHost CreateDbIfNotExists(此IHost主机)
    {
    使用(var scope=host.Services.CreateScope())
    {
    var services=scope.ServiceProvider;
    尝试
    {
    var accountDbContext=services.GetRequiredService();
    accountDbContext.Database.Recreated();
    var accountDbCreator=accountDbContext.GetService();
    accountDbCreator.CreateTables();
    }
    捕获(例外e){}
    尝试
    {
    var appDbContext=services.GetRequiredService();
    appDbContext.Database.recreated();
    var appDbCreator=appDbContext.GetService();
    appDbCreator.CreateTables();
    }
    捕获(例外e){}
    }
    返回主机;
    }
    }
    
    两个数据库是否使用相同的数据库?是的,当然。我还尝试在ea的
    appsettings.json
    中用两个不同的名称定义两个不同的连接字符串