Entity Framework Core Connection String - Variabile d'ambiente

asp.net asp.net-core c# entity-framework entity-framework-core

Domanda

Ho un'app core .net utilizzando il core della struttura dell'entità. Durante l'esecuzione di migrazioni di framework di entità o aggiornamenti tramite la riga di comando, ottengo un "valore non può essere nullo. Nome parametro: connectionString"

La stringa di connessione viene mantenuta come variabile di ambiente:

ConnectionStrings__SomeContextConnection  ...(localdb)\\MSSQLLocalDB...

Tuttavia, quando sposto quella stessa stringa di connessione in un file di configurazione .json:

"ConnectionStrings": {  
    "SomeContextConnection": "...(localdb)\\MSSQLLocalDB..." 
}

Quindi gli strumenti del framework di entità riconoscono la stringa di connessione senza problemi. Durante il debug del codice, in Startup.cs:

var connectionString = _config.GetConnectionString("SomeContextConnection");

la variabile connectionString viene impostata sulla stringa corretta quando la stringa viene archiviata in una delle due posizioni, ma si blocca quando si tenta di connettersi al database quando si utilizza l'ambiente var.

(nota: nel caso della variabile d'ambiente, la stringa di connessione è escapizzata, quindi va da

(localdb)\\MSSQLLocalDB...

a

(localdb)\\\\MSSQLLocalDB...

ma il problema persiste anche dopo aver rimosso i back-back in più)

AGGIORNAMENTO: quando la stringa di connessione viene spostata in una variabile di ambiente a livello di Windows, funziona correttamente. Sembra essere un problema solo quando si usano le variabili d'ambiente di Visual Studio.

Risposta popolare

Ti suggerisco di utilizzare una classe DesignTimeContextFactory per le migrazioni:

public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<MyContext>
{
    AmpContext IDesignTimeDbContextFactory<MyContext>.CreateDbContext(string[] args)
    {
        var connectionString = ConfigHelper.GetConnectionString();

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

        return new AmpContext(optionsBuilder.Options);
    }
}

la GetConnectionstring per me è così e la uso tutta la mia applicazione (cioè per il mio progetto Web API e per i test di integrazione):

public class ConfigHelper
{
    /// <summary>
    /// Gets the connectionstring from the appsettings.databasestring.json file in the solution root if there is no environment variable to be found
    /// </summary>
    /// <param name="solutionBasePath">Optional to not auto resolve the solution base path</param>
    /// <returns></returns>
    public static string GetConnectionString(string solutionBasePath = null)
    {
       //how to set it on IIS on the server: https://stackoverflow.com/a/36836533/1343595
        var environmentString = Environment.GetEnvironmentVariable("CUSTOMCONNSTR_MyContextDb");

        if (!string.IsNullOrEmpty(environmentString))
            return environmentString;

        if(!string.IsNullOrEmpty(solutionBasePath))
            return GetStringFromConfig(Path.Combine(solutionBasePath, "appsettings.databasestring.json"));

        var filePath = Path.Combine(GetSolutionBasePath(), "appsettings.databasestring.json");

        return GetStringFromConfig(filePath);
    }

    private static string GetStringFromConfig(string filePath)
    {
        IConfigurationRoot config = new ConfigurationBuilder()
            .AddJsonFile(filePath) //you can change the value of the connectionstring in the appsettings file and add it to gitignore so the change will not effect others
            .Build();

        var connectionString = config.GetConnectionString("MyContextDb");
        return connectionString;
    }

    /// <summary>
    /// Gets the current soution base path
    /// </summary>
    /// <returns></returns>
    public static string GetSolutionBasePath()
    {
        var appPath = PlatformServices.Default.Application.ApplicationBasePath;
        var binPosition = appPath.IndexOf("\\bin", StringComparison.Ordinal);
        var basePath = appPath.Remove(binPosition);

        var backslashPosition = basePath.LastIndexOf("\\", StringComparison.Ordinal);
        basePath = basePath.Remove(backslashPosition);
        return basePath;
    }
}


Related

Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché