繁体   English   中英

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

[英]Set a connectionString for a PostgreSQL database in Entity Framework outside the app.config

我有一个使用 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'.

那么 - 如果我的 connectionString 不是通过:base(connectionString)属性设置的,我该如何设置?

这个答案出现了一个解决方案。

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

您可以尝试使用 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 中,没有端口参数。

这就是我能够开始工作的...

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM