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 в качестве поставщика базы данных, взятый из этого источник:

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:

Ключевое слово не поддерживается: 'поставщик'.

Я думаю, что я близок к программному соединению, но не хватает чего-то небольшого. Что я могу сделать, чтобы устранить это исключение и правильно настроить это соединение программно? Нет приложения.config answers, я работаю в библиотеке классов, которая игнорирует приложение.config (см. комментарии принятого ответа на это вопрос). Эта программа должна оставаться такой, потому что она используется как плагин - она не (и не должна) работать самостоятельно. Спасибо заранее.

2 ответов


Ok, вот рабочий пример для вас, который я проверил, работает. Использование фиктивного кода-первая модель 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 в конструкторе:

using (var ctx = new SchoolContext("host=192.168.168.40;port=5432;...")) {                
            Console.WriteLine(ctx.Enrollments.ToArray());
        } 

и это все. Файл конфигурации полностью пуст во время этого, и он работает.


  1. вы смотрели Конфигурация На Основе Кода? Создать DbConfiguration класс с Открытый конструктор без параметров в той же сборке, что DbContext

    class MyConfiguration : System.Data.Entity.DbConfiguration
    {
        public MyConfiguration()
        {
            SetProviderServices("Npgsql", Npgsql.NpgsqlServices.Instance);
            SetProviderFactory("Npgsql", Npgsql.NpgsqlFactory.Instance);
        }
    }
    

    вот думаю DbContext должен использовать эту фабрику поставщика по умолчанию, и вы можете построить DbContext С помощью только строки подключения. Но если это в другой сборке, то у вас есть немного больше работы, но это можно найти в ссылке выше.

  2. потенциальная проблема с вышеуказанным решением заключается в том, что любая конфигурация в файле конфигурации будет иметь приоритет, поэтому, возможно, было бы безопаснее использовать опцию, описанную в здесь:

    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=против 110).aspx