Entity Framework Core Connection String - Variable de entorno

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

Pregunta

Tengo una aplicación .net core que utiliza el núcleo de framework de entidad. Al ejecutar migraciones o actualizaciones de framework de entidades a través de la línea de comando, obtengo un "valor no puede ser nulo. Nombre del parámetro: connectionString"

La cadena de conexión se mantiene como una variable de entorno:

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

Sin embargo, cuando muevo esa misma cadena de conexión exacta a un archivo de configuración .json:

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

Luego, las herramientas del marco de la entidad reconocen la cadena de conexión sin problemas. Al depurar el código, en Startup.cs:

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

la variable connectionString se establece en la cadena correcta cuando la cadena se almacena en cualquiera de las dos ubicaciones, pero se bloquea al intentar conectarse a la base de datos cuando se utiliza el entorno var.

(Nota: en el caso de la variable de entorno, la cadena de conexión se escapa por lo que va desde

(localdb)\\MSSQLLocalDB...

a

(localdb)\\\\MSSQLLocalDB...

pero el problema persiste incluso después de eliminar las barras invertidas adicionales)

ACTUALIZACIÓN: cuando la cadena de conexión se mueve a una variable de entorno de nivel de Windows, funciona bien. Parece ser solo un problema cuando se usan variables de entorno de Visual Studio.

Respuesta popular

Le sugiero que use una clase DesignTimeContextFactory para las migraciones:

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 para mí es así y la uso en toda mi aplicación (es decir, para mi proyecto de API web y para pruebas de integración):

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

Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué