Entity Framework 5.0 PostgreSQL (Npgsql) фабрика соединений по умолчанию
Я пытаюсь получить код EF 5.0, сначала работающий с PostgreSQL (поставщик Npgsql). У меня есть Npgsql 2.0.12.1, установленный через NuGet(ссылочная сборка-2.0.12.0). У меня Npgsql объявлен в приложении.config (как фабрика соединений по умолчанию, так и фабрика поставщиков):
<entityFramework>
<defaultConnectionFactory type="Npgsql.NpgsqlFactory, Npgsql, Version=2.0.12.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7" />
</entityFramework>
<system.data>
<DbProviderFactories>
<add name="Npgsql Data Provider"
invariant="Npgsql"
description="Data Provider for PostgreSQL"
support="FF"
type="Npgsql.NpgsqlFactory, Npgsql, Version=2.0.12.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7"/>
</DbProviderFactories>
</system.data>
у меня следующий тест успешно запущен:
[Test]
public void DatabaseConnection_DatabaseFactoryTest()
{
var factory = DbProviderFactories.GetFactory("Npgsql");
var conn = factory.CreateConnection();
conn.ConnectionString = _connectionString;
var npg = (NpgsqlConnection)conn;
var result = TestConnectionHelper(npg); // scalar select version(), nothing particular
Assert.AreEqual(result, "PostgreSQL 9.2.2, compiled by Visual C++ build 1600, 64-bit");
}
это означает, что по крайней мере экземпляр базы данных запущен и поставщик настроен успешно. Теперь я хочу использовать пользовательские контекст базы данных, унаследованный от DbContext, который будет привязан к тому же провайдеру и инициализирован через строку подключения:
public class InventoryContext : DbContext
{
public InventoryContext(string nameOrConnectionString) : base(nameOrConnectionString)
{
}
// mappings and properties, cut for conciseness
}
следующий тест терпит неудачу:
[Test]
public void DatabaseConnection_DatabaseContextTest()
{
using (var ctx = new InventoryContext(_connectionString))
{
//var db = ctx.Database;
ctx.InventoryObjects.Add(_inventoryObject); // exception here
ctx.SaveChanges();
}
}
он говорит:
Failed to set Database.DefaultConnectionFactory to an instance of the 'Npgsql.NpgsqlFactory, Npgsql, Version=2.0.12.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7' type as specified in the application configuration. See inner exception for details.
внутренним исключением является InvalidOperationException:
{"Constructor for type "Npgsql.NpgsqlFactory" is not found."}
Я думаю, что есть проблема со строкой подключения (не содержит провайдер Npgsql) :
"Server=127.0.0.1;Port=5432;User Id=postgres;Password=p4ssw0rd;Database=InventoryDatabase;";
каков самый элегантный способ решить эту проблему программно? Просто пробовал передать connectionString из приложения.config для конструктора контекста, он работает.
редактировать
Загруженный тестовый проект в Dropbox -решение VS2012, 10 МБ
1 ответов
копнул глубже в проблему, выяснил, что это вызвано тем фактом, что Npgsql ссылается на сборку EntityFramework 4.4.0. Решается следующим образом :
- добавлен пакет EF Nuget для тестирования проекта (который построен против FW 4.5);
- вручную добавлена ссылка на EntityFramework.dll версии 5 в проекте Npgsql2010 (по умолчанию Nuget добавляет 4.4.0);
- изменена привязка сборки в приложении Npgsql.config to " EntityFramework, Версия=5.0.0.0, Culture=нейтральным, PublicKeyToken=b77a5c561934e089";
- исправлено описанное выше "конструктор для типа "Npgsql.NpgsqlFactory " не найден ошибка при публикации конструктора;
-
исправлена следующая ошибка "невозможно привести NpgsqlFactory к IDbConnectionFactory" путем реализации интерфейса IDbConnectionFactory на NpgsqlFactory:
используя Система.Данные.Сущность.Инфраструктура;
...
открытый запечатанный класс NpgsqlFactory: DbProviderFactory, IServiceProvider, IDbConnectionFactory
...
публичное соединение с БД параметр "createconnection" (строка nameOrConnectionString)
{
возвращает новый NpgsqlConnection (nameOrConnectionString);
}
d
теперь я испытываю "ошибка: 3F000: схема "dbo" не существует", которая связана с EF. У меня есть сопоставление с PostgreSQL стандартная публичная схема в OnModelCreating DbContext: modelBuilder.Сущность.)(Однако ToTable ("TableName"," public"). С нетерпением жду решения этой проблемы.