c# - Entity Framework 5.0 PostgreSQL (Npgsql) 默认连接工厂

标签 c# .net database entity-framework-5 postgresql-9.2

我试图让 EF 5.0 代码首先与 PostgreSQL(Npgsql 提供程序)一起工作。我通过 NuGet 安装了 Npgsql 2.0.12.1(尽管引用的程序集是 2.0.12.0)。 我在 app.config 中声明了 Npgsql(默认连接工厂和提供者工厂):

<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 继承的自定义数据库上下文,它将绑定(bind)到同一个提供程序并通过连接字符串初始化:

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 从 app.config 传递给上下文的构造函数,它起作用了。
编辑
将测试项目上传到 Dropbox - VS2012 solution, 10 mb

最佳答案

深入研究问题,发现它是由 Npgsql 引用 EntityFramework 4.4.0 程序集这一事实引起的。解决方法如下:

  1. 将 EF Nuget 包添加到测试项目(针对 FW 4.5 构建);
  2. 在 Npgsql2010 项目中手动添加对 EntityFramework.dll 版本 5 的引用(Nuget 默认添加 4.4.0);
  3. 将 Npgsql app.config 中的程序集绑定(bind)更改为 "EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  4. 通过公开构造函数修复了上述“找不到类型“Npgsql.NpgsqlFactory”的构造函数错误;
  5. 通过在 NpgsqlFactory 上实现 IDbConnectionFactory 接口(interface)修复了以下错误“无法将 NpgsqlFactory 转换为 IDbConnectionFactory”:

    使用 System.Data.Entity.Infrastructure;
    ...
    公共(public)密封类 NpgsqlFactory : DbProviderFactory, IServiceProvider, IDbConnectionFactory
    ...
    public DbConnection CreateConnection(string nameOrConnectionString)
    {
    返回新的 NpgsqlConnection(nameOrConnectionString);

    d

现在我遇到与 EF 相关的“错误:3F000:架构“dbo”不存在”。不过,我在 DbContext 的 OnModelCreating 中映射到 PostgreSQL 标准公共(public)模式:modelBuilder.Entity().ToTable("TableName", "public")。期待这个问题的解决。

关于c# - Entity Framework 5.0 PostgreSQL (Npgsql) 默认连接工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14690567/

相关文章:

c# - 使用 IronPython 在 C# 中运行特定的 Python 函数

c# - 查找通过多个键分组的海量数据 C#

.net - 在 Fluent Nhibernate 中配置 "no-proxy"

c# - 不使用数据库数据可以使用DataGridView吗?

database - Paxos 与两阶段提交

database - 结果形式 sp_spaceused 在一个记录集中

c# - 参数异常 : Getting control 1's position in a group with only 1 controls when doing repaint

c# - C# 中的 Debug.WriteLine() - 它有什么作用?

c# - 如何在单独的线程上运行后台服务?

java - JDBC 在生产服务器上不工作