在app.config外部的Entity Framework中为PostgreSQL数据库设置connectionString

时间:2016-08-18 12:42:27

标签: c# entity-framework postgresql connection-string

我有一个使用PostgreSQL构建的数据库,我可以通过Entity Framework 6访问它。

直到最近,它才能顺利通过app.config connectionString:

<connectionStrings>
    <add
        name="fancyName"
        connectionString="Host=localhost; user id=allCanSee; password=notSoSecret; database=notHidden"
        providerName="Npgsql" />
</connectionStrings>

我们的主程序员对开放的connectionString并不满意,因为我们安装软件的每台计算机都可以读取它。因此,我们对所有内容进行了加密,并将加密存储在app.config

现在我遇到了一个新问题 - 我通过以下方式访问了我的数据库:

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

    public VersionContext() : base("name=fancyName")
    {
        System.Data.Entity.Database.SetInitializer<DatabaseContext>(null);
    }
}

但由于我的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);
    }
}

然后我按照以下方式访问它:

using (var context = new VersionContext())
{
    var entry = context.DatabaseVersion.FirstOrDefault();
    ...
}

但是这会从System.Data Keyword not supported: 'provider'.

中提出异常

从connectionString中删除provider会产生另一个例外:Keyword not supported: 'port'.

从connectionString中删除port会产生.Net SqlClient Data Provider的第三个例外:Login failed for user 'secretSecret'.

那么 - 如果没有通过:base(connectionString)属性设置我怎么设置我的connectionString?

3 个答案:

答案 0 :(得分:6)

this answer出现了一个解决方案。

app.config包含提供者:

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

通过让代码引用它,它可以创建连接:

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

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

并致电您的代码:

using (var context = new VersionContext())
{
    var entry = context.DatabaseVersion.FirstOrDefault();
    ...
}

通过这种方式,您可以使用加密的登录参数填充app.config,检索它们,然后将其传递给DbContext

答案 1 :(得分:1)

您可以尝试使用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;using System.Data.EntityClient;顺便说一下,是否支持端口?在您首先显示的connectionString中,没有端口参数。

答案 2 :(得分:0)

这就是我上班的能力...

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