C# 在app.config之外的实体框架中为PostgreSQL数据库设置connectionString

C# 在app.config之外的实体框架中为PostgreSQL数据库设置connectionString,c#,entity-framework,postgresql,connection-string,C#,Entity Framework,Postgresql,Connection String,我用PostgreSQL构建了一个数据库,我通过EntityFramework6访问它 直到最近,它还在app.configconnectionString中平稳运行: <connectionStrings> <add name="fancyName" connectionString="Host=localhost; user id=allCanSee; password=notSoSecret; database=notHidden"

我用PostgreSQL构建了一个数据库,我通过EntityFramework6访问它

直到最近,它还在
app.config
connectionString中平稳运行:

<connectionStrings>
    <add
        name="fancyName"
        connectionString="Host=localhost; user id=allCanSee; password=notSoSecret; database=notHidden"
        providerName="Npgsql" />
</connectionStrings>
但是由于我的
app.config
不再包含connectionString,我必须告诉数据库在哪里查找

我目前的尝试是这样的:

public static class VersionContextConnection
{
    public static string GetConnectionString() //Accessable form everywhere
    {
        var providerName = "Npgsql";
        var databaseName = decryptedName;
        var userName = decryptedUserName;
        var password = decryptedPassword;
        var host = decryptedHostName
        var port = 5432;

        return $"Provider={providerName}; " + $"Server={host}; " + $"Port={port}; " + 
            $"User Id={userName}; " + $"Password={password}; " + $"Database={databaseName};";
    }
}

public class VersionContext : DbContext
{
    public virtual DbSet<DatabaseNumber> DatabaseVersion { get; set; }

    public VersionContext() : base(VersionContextConnection.GetConnectionString())
    {
        System.Data.Entity.Database.SetInitializer<DatabaseContext>(null);
    }
}
但是这给了
系统一个例外。数据
关键字不受支持:“提供者”。

从connectionString中删除
提供程序会出现另一个异常:
关键字不受支持:“端口”。

从connectionString中删除
端口
会导致
.Net SqlClient数据提供程序
中的第三个异常:
用户“secretSecret”登录失败。


因此-如果未通过
:base(connectionString)
属性设置connectionString,如何设置connectionString?

您可以尝试使用EntityConnectionStringBuilder:

将静态方法修改为:

public static string GetConnectionString() //Accessable form everywhere
{
       var providerName = "Npgsql";
       var databaseName = decryptedName;
       var userName = decryptedUserName;
       var password = decryptedPassword;
       var host = decryptedHostName;
       var port = 5432;

       // Initializing the connection string builder for the provider
       SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder();
       sqlBuilder.ConnectionString = String.Format("Host={0};user id={1},password={2},database={3}",
       host, userName, password, databaseName);

       // Initialize the EntityConnectionStringBuilder.
       EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
       entityBuilder.Provider = providerName;
       entityBuilder.ProviderConnectionString = sqlBuilder.ToString();

       return entityBuilder.ToString();
}
并添加using语句:
using System.Data.SqlClient
顺便问一下,支持端口吗?在您首先显示的connectionString中,没有端口参数。

从中出现了一个解决方案

app.config
包含以下提供程序:

<providers>
    <provider 
        invariantName="Npgsql" <!-- this is what we need -->
        type="Npgsql.NpgsqlServices, EntityFramework6.Npgsql" />
</providers>
DbContext
设置为:

public class VersionContext : DbContext
{
    public virtual DbSet<DatabaseNumber> DatabaseVersion { get; set; }

    public VersionContext() : base(VersionContextConnection.GetDatabaseConnection(), true)
    {
        System.Data.Entity.Database.SetInitializer<DatabaseContext>(null); 
    }
}

有了这些,你可以用加密的登录参数填充你的
app.config
,检索它们,并将它们传递给你的
DbContext

,这就是我能做的

    public static DbConnection GetDatabaseConnection()
    {
      
        NpgsqlConnectionStringBuilder npgsqlConnectionStringBuilder = new NpgsqlConnectionStringBuilder();
        npgsqlConnectionStringBuilder.Host = "localhost";
        npgsqlConnectionStringBuilder.Port = 5432;
        npgsqlConnectionStringBuilder.Database = "database";
        npgsqlConnectionStringBuilder.Username = "postgres";
        npgsqlConnectionStringBuilder.Password = "postgres";

        var conn = new NpgsqlConnectionFactory().CreateConnection(npgsqlConnectionStringBuilder.ConnectionString.ToString());
        return conn;
    }

在运行时设置它怎么样?像这样的@Forlani这是一个解决方案,但是密码和用户名将在运行时公开……或者,它应该是server:port吗?而不是服务器;port?我不久前试过,@Forlani,但它也导致了en异常,它说它在
entityBuilder
中缺少
metadata
。我没有元数据可以提供,我尝试的结果是出现了更多的异常,这些异常没有使用npgsql进行连接。然而,我找到了一个解决方案(参见线程)。
public static class VersionContextConnection
{
    public static DbConnection GetDatabaseConnection()
    {
        var providerName = "Npgsql"; //Get this
        var databaseName = decryptedDatabaseName;
        var userName = decryptedUserName;
        var password = decryptedPassword;
        var host = decryptedHostName
        var port = 5432;

        //Insert it here
        var conn = DbProviderFactories.GetFactory(providerName).CreateConnection(); 
        conn.ConnectionString = $"Server={host}; " + $"Port={port}; " + 
            $"User Id={userName};" + $"Password={password};" + $"Database={databaseName};";

        return conn;
    }
}
public class VersionContext : DbContext
{
    public virtual DbSet<DatabaseNumber> DatabaseVersion { get; set; }

    public VersionContext() : base(VersionContextConnection.GetDatabaseConnection(), true)
    {
        System.Data.Entity.Database.SetInitializer<DatabaseContext>(null); 
    }
}
using (var context = new VersionContext())
{
    var entry = context.DatabaseVersion.FirstOrDefault();
    ...
}
    public static DbConnection GetDatabaseConnection()
    {
      
        NpgsqlConnectionStringBuilder npgsqlConnectionStringBuilder = new NpgsqlConnectionStringBuilder();
        npgsqlConnectionStringBuilder.Host = "localhost";
        npgsqlConnectionStringBuilder.Port = 5432;
        npgsqlConnectionStringBuilder.Database = "database";
        npgsqlConnectionStringBuilder.Username = "postgres";
        npgsqlConnectionStringBuilder.Password = "postgres";

        var conn = new NpgsqlConnectionFactory().CreateConnection(npgsqlConnectionStringBuilder.ConnectionString.ToString());
        return conn;
    }