dotnet核心-实体框架-多个DbContext选择错误的DbContext

时间:2020-01-29 00:35:31

标签: c# .net-core entity-framework-core

我有两个数据库。首次启动时,该解决方案将检查数据库,然后通过迁移创建它们。但是,两个DB的迁移都存在,但是当它们被调用以从启动时创建上下文时,实际上是将其转到错误的服务,我不知道为什么。

这里是创建上下文的代码。

public static class StartupCATALOGExtension
{
    public static void EnsureCATALOGMigrationAndInitialise(this IApplicationBuilder app)
    {
        if (app == null) throw new ArgumentNullException(nameof(app));

        using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
        {
            var context = serviceScope.ServiceProvider.GetService<CATALOGContext>();
            var cryptoService = serviceScope.ServiceProvider.GetService<ICryptoService>();

            context.Database.Migrate();
            serviceScope.ServiceProvider.GetService<ICATALOGCounterInitialiser>()
                .InitialiseCATALOGCounters(context);
            serviceScope.ServiceProvider.GetService<ICATALOGStateInitialiser>().CATALOGInitialiseStates(context);
            serviceScope.ServiceProvider.GetService<ICATALOGSuburbInitialiser>().CATALOGInitialiseSuburbs(context);
            serviceScope.ServiceProvider.GetService<IRoleInitialiser>().InitialiseRoles(context);
            serviceScope.ServiceProvider.GetService<ITenantAndUserInitialisations>()
                .InitialiseTenantsAndUsers(context, cryptoService);
        }
    }
}

}

我可以走到这一行:

var context = serviceScope.ServiceProvider.GetService<CATALOGContext>();

这时,它转到Startup.cs文件,尤其是服务部分。我在这里:

        services
            // Add framework services.
            .AddOptions()

            .AddDbContext<CATALOGContext>(options => options
                .UseSqlServer(Configuration
                    .GetConnectionString("CatalogConnection"), b => b.MigrationsAssembly("JobsLedger.CATALOG")))

            .AddDbContext<DATAContext>(options => options
                .UseSqlServer(Configuration
                    .GetConnectionString("TenantDbConnection"), a => a.MigrationsAssembly("JobsLedger.DATA")))

它专门用于:

            .AddDbContext<CATALOGContext>(options => options
                .UseSqlServer(Configuration
                    .GetConnectionString("CatalogConnection"), b => b.MigrationsAssembly("JobsLedger.CATALOG")))

但是无论出于何种原因,我都无法理解它是否会去其他服务...

            .AddDbContext<DATAContext>(options => options
                .UseSqlServer(Configuration
                    .GetConnectionString("TenantDbConnection"), a => a.MigrationsAssembly("JobsLedger.DATA")))

我不知道为什么它会跳过它应该去的服务并最终到达另一个数据库的服务。

为什么要去第二个服务,更重要的是如何使它去正确的服务?

其他信息

为完整起见,以下是我的appsettings文件中的连接字符串:

"ConnectionStrings": {
    "CatalogConnection": "Server=(localdb)\\mssqllocaldb;Database=catalogDb;Trusted_Connection=True;MultipleActiveResultSets=true",
    "TenantDbConnection": "Server=(localdb)\\mssqllocaldb;Database=masterDb;Trusted_Connection=True;MultipleActiveResultSets=true"
},

这是迁移文件:

using JobsLedger.AUTHORISATION.API.SessionMiddleware;
using JobsLedger.CATALOG;
using JobsLedger.DATA;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using System.IO;

namespace JobsLedger.API {
    public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<CATALOGContext> {
        public CATALOGContext CreateDbContext(string[] args) {
            IConfigurationRoot configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .Build();

            var builder = new DbContextOptionsBuilder<CATALOGContext>();

            var userSession = new UserSession {
                ConnectionString = configuration.GetConnectionString("CatalogConnection")
            };

            builder.UseSqlServer(userSession.ConnectionString);

            return new CATALOGContext(builder.Options, userSession);
        }
    }
}
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<DATAContext> {
    public DATAContext CreateDbContext(string[] args) {
        IConfigurationRoot configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json")
            .Build();

        var builder = new DbContextOptionsBuilder<DATAContext>();

        var userSession = new UserSession {
            ConnectionString = configuration.GetConnectionString("TenantDbConnection")
        };
        return new DATAContext(builder.Options, userSession);
    }
}

1 个答案:

答案 0 :(得分:0)

对这个问题的兴趣浓厚,我今晚做了一些研究。

我加载了实际错误-至少是最后一部分,我发现罗恩·米勒(Rowan Miller)发了THIS个帖子。

基本上,我需要使用通用选项类型。因此,我在每个DbContext中更改了构造函数以反映其实际含义。

对于我的CATALOGContext,我对此进行了更改:

public CATALOGContext(DbContextOptions options, IUserSession userSession) : base(options)
        {
            _userSession = userSession;
        }

对此:

public CATALOGContext(DbContextOptions<CATALOGContext> options, IUserSession userSession) : base(options)
        {
            _userSession = userSession;
        }

..现在它选择要使用的正确上下文。