2013-02-04 50 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