Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架核心连接字符串-环境变量_C#_Asp.net_Entity Framework_Asp.net Core_Entity Framework Core - Fatal编程技术网

C# 实体框架核心连接字符串-环境变量

C# 实体框架核心连接字符串-环境变量,c#,asp.net,entity-framework,asp.net-core,entity-framework-core,C#,Asp.net,Entity Framework,Asp.net Core,Entity Framework Core,我有一个使用entity framework core的.net core应用程序。当通过命令行运行实体框架迁移或更新时,我得到一个“值不能为null。参数名称:connectionString” 连接字符串保留为环境变量: ConnectionStrings__SomeContextConnection ...(localdb)\\MSSQLLocalDB... 但是,当我将完全相同的连接字符串移动到.json配置文件中时: "ConnectionStrings": { "So

我有一个使用entity framework core的.net core应用程序。当通过命令行运行实体框架迁移或更新时,我得到一个“值不能为null。参数名称:connectionString”

连接字符串保留为环境变量:

ConnectionStrings__SomeContextConnection  ...(localdb)\\MSSQLLocalDB...
但是,当我将完全相同的连接字符串移动到.json配置文件中时:

"ConnectionStrings": {  
    "SomeContextConnection": "...(localdb)\\MSSQLLocalDB..." 
}
然后,实体框架工具识别连接字符串而不会出现问题。 调试代码时,在Startup.cs中:

var connectionString = _config.GetConnectionString("SomeContextConnection");
当字符串存储在两个位置中的任何一个位置时,connectionString变量被设置为正确的字符串,但是当使用环境变量尝试连接到数据库时,它会崩溃

(注意:在环境变量的情况下,连接字符串是转义的,因此从

(localdb)\\MSSQLLocalDB...

但即使在删除额外的背面斜线后,问题仍然存在)

更新:
当连接字符串移动到Windows级别的环境变量中时,它可以正常工作。似乎只有在使用Visual Studio环境变量时才会出现问题。

如果在
(localdb)
之后删除双反斜杠,使其只有一个反斜杠,则会起作用

因此,一旦您在环境变量中纠正了这一点,它应该如下所示:

Server=(localdb)\MSSQLLocalDB…

我建议您为迁移使用一个类:

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);
    }
}
公共类DesignTimeDbContextFactory:IDesignTimeDbContextFactory
{
AmpContext IDesignTimeDbContextFactory.CreateDbContext(字符串[]args)
{
var connectionString=ConfigHelper.GetConnectionString();
var optionsBuilder=new DbContextOptionsBuilder();
optionsBuilder.UseSqlServer(connectionString);
返回新的AmpContext(optionsBuilder.Options);
}
}
GetConnectionstring对我来说是这样的,我在整个应用程序中都使用它(用于我的Web API项目和集成测试):

公共类ConfigHelper
{
/// 
///如果找不到环境变量,则从解决方案根目录中的appsettings.databasestring.json文件获取connectionstring
/// 
///不自动解析解决方案基本路径的可选选项
/// 
公共静态字符串GetConnectionString(字符串solutionBasePath=null)
{
//如何在服务器上的IIS上设置它:https://stackoverflow.com/a/36836533/1343595
var environmentString=Environment.GetEnvironmentVariable(“CUSTOMCONNSTR_MyContextDb”);
如果(!string.IsNullOrEmpty(environmentString))
返回环境字符串;
如果(!string.IsNullOrEmpty(solutionBasePath))
返回GetStringFromConfig(Path.Combine(solutionBasePath,“appsettings.databasestring.json”);
var filePath=Path.Combine(GetSolutionBasePath(),“appsettings.databasestring.json”);
返回GetStringFromConfig(文件路径);
}
私有静态字符串GetStringFromConfig(字符串文件路径)
{
IConfigurationRoot config=new ConfigurationBuilder()
.AddJsonFile(filePath)//您可以更改appsettings文件中connectionstring的值,并将其添加到gitignore中,这样更改不会影响其他文件
.Build();
var connectionString=config.GetConnectionString(“MyContextDb”);
返回连接字符串;
}
/// 
///获取当前的soution基路径
/// 
/// 
公共静态字符串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(反斜杠位置);
返回基本路径;
}
}

尝试放置一个反斜杠,这是我在上面的“注意”中提到的,但没有帮助。我认为这与Project.Json有关,如果有,请检查启动应用程序或DB层中是否有注释行。JSON文件中不能有任何注释行。我删除了所有注释,这可能会在以后引起问题,但这个问题没有得到解决。@Montecristo Yarrgh正试图帮助您,我建议您下次有人这样做时,在回答时更加温和
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);
    }
}
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;
    }
}