简体   繁体   English

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

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

I have a database build with PostgreSQL, which I access through Entity Framework 6.我有一个使用 PostgreSQL 构建的数据库,我通过 Entity Framework 6 访问它。

Until recently it ran smoothly through an app.config connectionString:直到最近它通过app.config connectionString 顺利运行:

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

Our lead programmer is not happy about an open connectionString, since every computer we install the software on can read it.我们的首席程序员对打开的 connectionString 并不满意,因为我们安装软件的每台计算机都可以读取它。 We therefore encrypted everything, and stored the encryption in the app.config .因此,我们加密了所有内容,并将加密存储在app.config

Now I have a new problem - I have accessed my database the following way:现在我遇到了一个新问题 - 我通过以下方式访问了我的数据库:

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

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

But since my app.config no longer contains the connectionString, I must tell the database where to look.但是由于我的app.config不再包含 connectionString,我必须告诉数据库在哪里查找。

My current attempt is something like this:我目前的尝试是这样的:

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

Then I'd access it as follow:然后我会按如下方式访问它:

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

But this gives an exception from System.Data saying Keyword not supported: 'provider'.但这给出了System.Data一个例外, Keyword not supported: 'provider'.

Removing provider from the connectionString gives another exception: Keyword not supported: 'port'.从 connectionString 中删除provider导致另一个异常: Keyword not supported: 'port'.

Removing port from the connectionString gives a third exception from .Net SqlClient Data Provider : Login failed for user 'secretSecret'.从 connectionString 中删除port导致.Net SqlClient Data Provider的第三个异常: Login failed for user 'secretSecret'.

So - how do I set my connectionString, if it's not set through the :base(connectionString) property?那么 - 如果我的 connectionString 不是通过:base(connectionString)属性设置的,我该如何设置?

A solution emerged from this answer .这个答案出现了一个解决方案。

The app.config contains the providers: app.config包含提供程序:

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

By letting the code refer to that, it can create the connection:通过让代码引用它,它可以创建连接:

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

Set the DbContext as such: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); 
    }
}

And call your code:并调用您的代码:

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

With such, you can populate your app.config with encrypted login parameters, retrieve them, and pass them to your DbContext .这样,您可以使用加密的登录参数填充app.config ,检索它们,并将它们传递给您的DbContext

You can try using EntityConnectionStringBuilder:您可以尝试使用 EntityConnectionStringBuilder:

Modify your static method to:将您的静态方法修改为:

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

And add the using statements: using System.Data.SqlClient;并添加 using 语句: using System.Data.SqlClient; and using System.Data.EntityClient;using System.Data.EntityClient; By the way, is port supported?顺便问一下,是否支持端口? In the connectionString that you showed first, there is no port parameter.在您首先显示的 connectionString 中,没有端口参数。

This is what I as able to get to work...这就是我能够开始工作的...

    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