2017-05-17 5 views
2

Ich versuche, die Verbindungszeichenfolge meines DbContext in Abhängigkeit von jedem HTTP-Anfrage-Header festzulegen. Ist es möglich, dies in .NET Core zu tun? Ich habe es in MVC5 gemacht, aber ich kann es nicht in .NET Core implementieren..NET Core DbContext dynamische Verbindungszeichenfolge

Bei

public void ConfigureServices(IServiceCollection services) 
{ 
    // ... 
} 

Ich weiß nicht, den HTTP-Header, also wo kann ich es tun?

+0

MVC hat keine Verbindungszeichenfolgen. Es hat nichts mit Datenbanken zu tun. * EF * tut es. Haben Sie versucht, die Verbindungszeichenfolge wie bei der vorherigen EF-Version festzulegen? Was hast du versucht? Bitte postet den Code –

+0

BTW was meinst du dynamisch? Möchten Sie unterschiedliche Datenbanken pro Anforderung auswählen, unterschiedliche Anmeldeinformationen pro Endbenutzer verwenden oder möchten Sie keine Konfigurationsdatei für die Verbindungszeichenfolge verwenden? Warum nicht einfach die in der Konfigurationsdatei gespeicherte Verbindungszeichenfolge verwenden? –

+0

Was ich versuche zu erreichen ist: Ich versuche, abhängig von jeder HTTP-Anfrage eine Verbindung zu verschiedenen Datenbanken herzustellen. Auf dem Header der HTTP-Anfrage sende ich den Namen des connectionString. – tunoandsuno

Antwort

3

Sie sollten in der Lage sein, so etwas zu tun, um den HTTP-Request-Inhalt innerhalb der DbContext Typs Instanziierung zu verwenden:

using Microsoft.AspNetCore.Http; 
using Microsoft.EntityFrameworkCore; 
using Microsoft.Extensions.DependencyInjection; 
using Microsoft.Extensions.DependencyInjection.Extensions; 

public void ConfigureServices(IServiceCollection services) 
{ 
    // ... 

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 
    services.AddScoped<HttpContext>(p => p.GetService<IHttpContextAccessor>()?.HttpContext); 
    services.AddDbContext<MyDbContext>(); 

    var descriptor = new ServiceDescriptor(
     typeof(DbContextOptions<MyDbContext>), 
     DbContextOptionsFactory, 
     ServiceLifetime.Scoped); 

    var descriptorNonGeneric = new ServiceDescriptor(
     typeof(DbContextOptions), 
     typeof(DbContextOptions<MyDbContext>), 
     ServiceLifetime.Scoped); 

    services.Replace(descriptor); 
    services.Replace(descriptorNonGeneric); 

    // ... 
} 

private DbContextOptions<MyDbContext> DbContextOptionsFactory(IServiceProvider provider) 
{ 
    var httpContext = provider.GetService<HttpContext>(); 
    // here we have the complete HttpContext 
    var myHeader = httpContext.Request.Headers["MyHeader"]; 
    var connectionString = GetConnectionStringFromHeader(myHeader); 

    var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>(); 
    optionsBuilder.UseSqlServer(connectionString); 

    return optionsBuilder.Options; 
} 

Da die AddDbContext<TDbContext> Erweiterungsmethode von EFCore bereits ein DbContextOptions als Singleton registrieren wird, brauchen wir um diese Registrierung zu überschreiben und unsere eigene DbContextOption Factory-Methode hinzuzufügen, die HttpContext verwendet und mit Scoped Lebensdauer ausgeführt wird.

Auf diese Weise können wir die Optionen (einschließlich der Verbindungszeichenfolge) bei jeder Anfrage ändern.

+0

Ich werde das versuchen. Was ich versuche zu tun, ist eine Verbindung zu verschiedenen connectionStrings abhängig von der HTTP-Anfrage Header. Ich sende die Connectionstring im HTTP-Request-Header. – tunoandsuno

+0

Funktioniert nur beim ersten Laden. Nicht für jede HTTP-Anfrage. Wie kann ich das erreichen? – tunoandsuno

+0

@tunoandsuno Bearbeitete die Antwort. Versuchen Sie es mit dieser Lösung. –

Verwandte Themen