我有一个使用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?
答案 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;
}