簡體   English   中英

為什么啟動中的連接字符串會干擾 EF Core 遷移?

[英]Why does the connection string in Startup interfere with EF Core migration?

我想將遷移添加到項目中,因此我實現了IDesignTimeDbContextFactory接口。

我已將ContextFactory放置在項目的表示層中,其中上下文位於數據庫層中。

在啟動時,我像這樣注入上下文連接字符串:

services.AddTransient<FooDbContext>().AddDbContext<FooDbContext>(options => options.UseSqlServer(Environment.GetEnvironmentVariable("FOODB_CONNECTIONSTRING")));

ContextFactory (遷移是這樣實現的):

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

        var builder = new DbContextOptionsBuilder<FooDbContext>();

        var connectionString = configuration.GetConnectionString("DefaultConnection");

        builder.UseSqlServer(connectionString);

        return new FooDbContext(builder.Options);
    }
}

因此,如果我在啟動時注釋掉注入,我可以運行遷移,但是在此代碼處於活動狀態時,我會收到以下錯誤:

System.ArgumentNullException:值不能為 null。 (參數“連接字符串”)

在 Microsoft.EntityFrameworkCore.Utilities.Check.NotEmpty(字符串值,字符串參數名稱)
在 Microsoft.EntityFrameworkCore.SqlServerDbContextOptionsExtensions.UseSqlServer(DbContextOptionsBuilder optionsBuilder, String connectionString, Action 1 sqlServerOptionsAction) at Wegister.Startup.<>c.<ConfigureServices>b__7_1(DbContextOptionsBuilder options) in C:\Users\Daphne\Source\Repos\SalomeCodes\Wegister\Wegister\Wegister\Startup.cs:line 66 at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.<>c__DisplayClass1_0 2.b__0(IServiceProvider p, DbContextOptionsBuilder b)
在 Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.CreateDbContextOptions[TContext](IServiceProvider applicationServiceProvider, Action 2 optionsAction) at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.<>c__DisplayClass10_0 1.b__0(IServiceProvider p)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite,RuntimeResolverContext 上下文)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor 2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor 2.VisitCallSite(ServiceCallSite callSite, TArgument 參數)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite,ServiceProviderEngineScope 范圍)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.b__0(ServiceProviderEngineScope 范圍)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(鍵入 serviceType,ServiceProviderEngineScope serviceProviderEngineScope)> 在 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(鍵入 serviceType)
在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider 提供程序,類型 serviceType)
在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider 提供程序)
在 Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.<>c__10 1.<AddCoreServices>b__10_1(IServiceProvider p) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor 2.VisitCallSiteMain(ServiceCallSite callSite, TArgument 參數)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite,RuntimeResolverContext 上下文,ServiceProviderEngineScope serviceProviderEngine,RuntimeResolverLock lockType)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite,RuntimeResolverContext 上下文)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor 2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor .VisitCallSiteMain(ServiceCallSite callSite, TArgument 參數)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite,RuntimeResolverContext 上下文,ServiceProviderEngineScope serviceProviderEngine,RuntimeResolverLock lockType)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite,RuntimeResolverContext 上下文)
在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor 2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetServices[T](IServiceProvider provider) at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.FindContextTypes() at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.FindContextType(String name) at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType) at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0 2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetServices[T](IServiceProvider provider) at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.FindContextTypes() at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.FindContextType(String name) at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType) at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0 1.b__0() 在 Microsoft.EntityFrameworkCore。 Design.OperationExecutor.OperationBase.Execute(動作動作)

值不能是 null。 (參數“連接字符串”)

所以依賴注入會覆蓋這個連接字符串——但是為什么呢?

什么是解決方案,所以我仍然可以運行代碼和遷移? 因為當我在連接字符串上使用依賴注入啟動代碼時,應用程序不知道在哪里連接?

在啟動時用這段代碼解決了它:

IConfigurationRoot configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .Build();

var connstring = Configuration["WEGISTERDB_CONNECTIONSTRING"] ?? configuration.GetConnectionString("WEGISTERDB_CONNECTIONSTRING");

它也使得刪除IDesignTimeDbContextFactory成為可能。不知何故,遷移需要一個已經設置的連接字符串,因為它無法將連接字符串作為環境變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM