Entity Framework 6 Программно подключается к Postgres
Я работаю над программным установлением соединения с PostgresSQL с использованием Entity Framework 6. У меня есть этот класс:
public class ClearspanDatabaseContext : DbContext
с этим конструктором:
public ClearspanDatabaseContext()
: base(buildConnectionString())
{
}
Здесь статический метод, который делает программную цепочку соединений:
private static string buildConnectionString()
{
RegisterDbProvider("Npgsql", ".Net Framework Data Provider for Postgresql", "Npgsql Data Provider", "Npgsql.NpgsqlFactory, Npgsql");
EntityConnectionStringBuilder entityConnectionStringBuilder = new EntityConnectionStringBuilder();
entityConnectionStringBuilder.Provider = "Npgsql";
entityConnectionStringBuilder.ProviderConnectionString = "host=192.168.168.140;Port=5432;username=ClearspanDevLogin;password=*******;database=ClearspanWebServerDev";
return entityConnectionStringBuilder.ToString();
}
И вот метод, который регистрирует Npgsql в качестве поставщика базы данных, взятый из этого source:
public static bool RegisterDbProvider(string invariant, string description, string name, string type)
{
try
{
DataSet ds = ConfigurationManager.GetSection("system.data") as DataSet;
foreach (DataRow row in ds.Tables[0].Rows)
{
if (row["InvariantName"].ToString() == invariant)
{
return true;
}
}
ds.Tables[0].Rows.Add(name, description, invariant, type);
return true;
}
catch
{
}
return false;
}
Это создает такую строку:
"provider=Npgsql;provider connection string=\"host=192.168.168.140;Port=5432;username=ClearspanDevLogin;password=********;database=ClearspanWebServerDev\""
Но я получаю ArgumentException
:
Ключевое слово не поддерживается: "поставщик".
Я думаю, что я близок к программному соединению, но мне не хватает чего-то маленького. Что я могу сделать для устранения этого исключения и правильно настроить это соединение программно? Нет ответов app.config, я работаю в библиотеке классов, которая игнорирует app.config(см. Комментарии принятого ответа на этот question). Эта программа должна оставаться такой, потому что она используется как плагин - она не работает (и не должна) запускаться сама по себе. Спасибо заранее.
Ответы
Ответ 1
Хорошо, вот рабочий пример для вас, который я проверил, работает.
Использование фиктивного кода - первая модель EF 6 + пользовательский класс DbConfiguration:
public class Enrollment {
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
}
[DbConfigurationType(typeof (NpgsqlConfiguration))]
public class SchoolContext : DbContext {
public SchoolContext(string cs) : base(cs) {
}
public DbSet<Enrollment> Enrollments { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
}
}
class NpgsqlConfiguration : System.Data.Entity.DbConfiguration
{
public NpgsqlConfiguration()
{
SetProviderServices("Npgsql", Npgsql.NpgsqlServices.Instance);
SetProviderFactory("Npgsql", Npgsql.NpgsqlFactory.Instance);
SetDefaultConnectionFactory(new Npgsql.NpgsqlConnectionFactory());
}
}
Затем вместо вашего buildConnectionString() просто передайте строку postgre connection в конструкторе:
using (var ctx = new SchoolContext("host=192.168.168.40;port=5432;...")) {
Console.WriteLine(ctx.Enrollments.ToArray());
}
И это все. Файл Config полностью пуст во время этого, и он работает.
Ответ 2
-
Вы просмотрели Code-Based Configuration? Создайте класс DbConfiguration
с открытым конструктором без параметров в той же сборке, что и ваш DbContext
class MyConfiguration : System.Data.Entity.DbConfiguration
{
public MyConfiguration()
{
SetProviderServices("Npgsql", Npgsql.NpgsqlServices.Instance);
SetProviderFactory("Npgsql", Npgsql.NpgsqlFactory.Instance);
}
}
Теперь я думаю, что DbContext
должен использовать этот провайдер factory по умолчанию, и вы можете построить DbContext
только с строкой соединения. Но если это в другой сборке, то у вас есть немного больше работы, но это можно найти в ссылке выше.
-
Потенциальная проблема с вышеупомянутым решением заключается в том, что любая конфигурация в файле конфигурации будет иметь приоритет, поэтому, возможно, было бы безопаснее использовать опцию, описанную в здесь:
var conn = DbProviderFactories.GetFactory("MY_CONN_PROVIDER").CreateConnection();
conn.ConnectionString = "MY_CONN_STR";
new DbContext(conn, true);
где ваш провайдер "Npgsql"
, который был зарегистрирован в RegisterDbProvider
выше.
Также см. https://msdn.microsoft.com/en-us/library/dd0w4a2z(v=vs.110).aspx