엔터티 프레임 워크 핵심 연결 문자열 - 환경 변수

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

문제

엔티티 프레임 워크 코어를 사용하는 .net 핵심 응용 프로그램이 있습니다. 명령 줄을 통해 엔티티 프레임 워크 마이그레이션 또는 업데이트를 실행할 때 "값이 null 일 수 없습니다. 매개 변수 이름 : connectionString"

연결 문자열은 환경 변수로 유지됩니다.

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

그러나, 그 정확한 연결 문자열을 .json 설정 파일로 옮길 때 :

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

그런 다음 엔터티 프레임 워크 도구는 문제없이 연결 문자열을 인식합니다. Startup.cs에서 코드를 디버깅 할 때 :

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

connectionString 변수는 문자열이 두 위치 중 하나 에 저장 될 때 올바른 문자열로 설정되지만 환경 var를 사용할 때 데이터베이스에 연결하려고하면 충돌합니다.

(참고 : 환경 변수의 경우 연결 문자열이 이스케이프 처리되므로

(localdb)\\MSSQLLocalDB...

(localdb)\\\\MSSQLLocalDB...

하지만 여분의 백 슬래시를 제거한 후에도 문제가 지속됩니다)

업데이트 : 연결 문자열을 Windows 수준 환경 변수로 이동할 때 제대로 작동합니다. Visual Studio 환경 변수를 사용할 때만 문제가 될 것으로 보입니다.

인기 답변

마이그레이션을 위해 DesignTimeContextFactory 클래스를 사용하는 것이 좋습니다.

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);
    }
}

내게는 GetConnectionstring이 같고 내 응용 프로그램 (웹 API 프로젝트 및 통합 테스트 용) 전체에 걸쳐 사용합니다.

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

아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.