2013-02-04 54 views
9

我试图让EF 5.0代码第一次使用PostgreSQL(Npgsql提供程序)。我通过NuGet安装了Npgsql 2.0.12.1(虽然引用的程序集是2.0.12.0)。 我在Npgsql的声明的app.config(包括默认连接工厂和供应商的工厂):实体框架5.0 PostgreSQL(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继承自定义数据库方面将通过连接字符串被捆绑到同一个供应商和初始化:

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;"; 

什么是编程方式解决这一问题的最优雅的方式?只是尝试从app.config传递connectionString到上下文的构造函数,它的工作原理。
编辑
上传测试项目,Dropbox的 - VS2012 solution, 10 mb

+0

嗨! nuget包中的最后一个.1是因为我无法更新2.0.12包。包里有一个丢失的文件,我不得不更新它。但请放心,Npgsql二进制文件与2.0.12版本相同。 :)你介意给我这个示例项目,让我可以看看它吗?我认为这可能是Npgsql中的一个错误,它可能会遗漏EF期望的构造函数。我的电子邮件地址是npgsql dor org的francisco。提前致谢。 –

+0

版本不是问题,虽然我失去了一些时间找出为什么在运行时没有找到程序集。这一点是真正的连接字符串配置,尤其是在我的生产环境中,我无法使用/修改.config文件(在IIS限制中发布的WPF XBAP应用程序)。将在几个小时内发送给您示例项目。 – Jaded

+0

发送示例项目,如果其他人想要查看,则添加dropbox下载链接。 – Jaded

回答

7

更深入地挖掘问题,发现它是由这一事实,是Npgsql的引用的EntityFramework 4.4.0装配引起的。解决如下:

  1. 增加了EF Nuget包测试项目(这是建立对FW 4.5);
  2. 在Npgsql2010项目中手动添加对EntityFramework.dll版本5的引用(Nuget默认添加了4.4.0);
  3. 更改组件的app.config Npgsql的结合“的EntityFramework,版本= 5.0.0.0,文化=中性公钥= b77a5c561934e089”;
  4. 上述修正了描述的“构造类型‘Npgsql.NpgsqlFactory’未找到误差通过使构造公众;
  5. 修正以下错误‘无法铸造NpgsqlFactory到通过实施IDbConnectionFactory接口IDbConnectionFactory’在NpgsqlFactory上:

    using System.Data.Entity.Infrastructure;
    ...
    公共密封类NpgsqlFactory:DbProviderFactory,IServiceProvider的,IDbConnectionFactory
    ...
    公众的DbConnection创建连接(字符串nameOrConnectionString)
    {
    回报新NpgsqlConnection(nameOrConnectionString);
    }
    d

现在我遇到了 “错误:3F000:模式 ”DBO“ 不存在”,这是关系到EF。我已经在DbContext的OnModelCreating:modelBuilder.Entity()ToTable(“TableName”,“public”)中映射到了PostgreSQL标准公共模式。期待解决这个问题。

+0

太棒了!我将立即添加报告缺失的部分:构造函数可见性和接口实现。感谢您检查。 –

+1

我想我跳得太快了。在检查msdn文档时,我注意到SqlClientFactory是一件事,而SqlConnectionFactory是另一件事。 NpgsqlFactory等同于SqlClientFactory。为了解决这个问题,我们需要创建另一个名为NpgsqlConnectionFactory的类,它将绑定到实体框架支持。对不起。我会检查我们将如何做到这一点。 –

+0

我已经放弃使用EntityFramework与PostgreSQL和Npgsql这些问题已得到解决。没有办法,我会投入生产,直到它更稳定。 – Jammer