2013-02-04 30 views
9

Tôi đang cố gắng để có được mã EF 5.0 đầu tiên làm việc với PostgreSQL (nhà cung cấp Npgsql). Tôi có Npgsql 2.0.12.1 cài đặt thông qua NuGet (tham chiếu lắp ráp là 2.0.12.0 mặc dù). Tôi có Npgsql khai báo trong app.config (cả hai nhà máy kết nối mặc định và nhà máy cung cấp): thử nghiệmEntity Framework 5.0 Nhà máy kết nối mặc định 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> 

Tôi đã sau chạy thành công:

[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");    
} 

Điều đó có nghĩa ít nhất cơ sở dữ liệu ví dụ đang chạy và nhà cung cấp được định cấu hình thành công. Bây giờ những gì tôi muốn là sử dụng bối cảnh cơ sở dữ liệu tùy chỉnh được thừa kế từ DbContext đó sẽ được gắn với cùng một nhà cung cấp và khởi tạo thông qua chuỗi kết nối:

public class InventoryContext : DbContext 
{ 
    public InventoryContext(string nameOrConnectionString) : base(nameOrConnectionString) 
    { 
    } 
    // mappings and properties, cut for conciseness 
} 

thử nghiệm sau thất bại:

[Test] 
public void DatabaseConnection_DatabaseContextTest() 
{ 
    using (var ctx = new InventoryContext(_connectionString)) 
    { 
     //var db = ctx.Database; 
     ctx.InventoryObjects.Add(_inventoryObject); // exception here 
     ctx.SaveChanges(); 
    } 
} 

Nó nói

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. 

Ngoại lệ bên trong là InvalidOperationException:

{"Constructor for type \"Npgsql.NpgsqlFactory\" is not found."} 

Tôi đoán có một vấn đề với chuỗi kết nối (nó không chứa cung cấp Npgsql):

"Server=127.0.0.1;Port=5432;User Id=postgres;Password=p4ssw0rd;Database=InventoryDatabase;"; 

cách thanh lịch nhất để giải quyết vấn đề này theo chương trình là gì? Chỉ cần cố gắng đi qua connectionString từ app.config đến constructor của context, nó hoạt động.
chỉnh sửa
Tải Lên thử nghiệm dự án để Dropbox - VS2012 solution, 10 mb

+0

Xin chào! Điều này .1 cuối cùng trong gói nuget là vì tôi không thể cập nhật gói 2.0.12. Có một tệp bị thiếu trong gói và tôi phải cập nhật nó. Nhưng hãy yên tâm rằng nhị phân Npgsql giống như phiên bản 2.0.12. :) Bạn có nhớ gửi cho tôi dự án mẫu này để tôi có thể xem nó không? Tôi nghĩ rằng đây có thể là một lỗi trong Npgsql mà có thể thiếu một nhà xây dựng EF đang mong đợi. Email của tôi là francisco tại npgsql dor org. Cảm ơn trước. –

+0

Phiên bản không phải là một vấn đề mặc dù tôi đã mất một số thời gian tìm hiểu lý do tại sao lắp ráp không được tìm thấy trong thời gian chạy. Điểm thực sự là trong cấu hình chuỗi kết nối, đặc biệt là trong thực tế trong môi trường sản xuất của tôi, tôi không thể sử dụng/sửa đổi các tệp .config (ứng dụng WPF XBAP được xuất bản trong các hạn chế IIS). Sẽ gửi cho bạn dự án mẫu trong vài giờ. – Jaded

+0

Dự án mẫu đã gửi, thêm liên kết tải xuống hộp kéo nếu người khác muốn xem. – Jaded

Trả lời

7

Dug sâu hơn vào vấn đề, phát hiện ra rằng nó được gây ra bởi thực tế rằng Npgsql là tham khảo EntityFramework 4.4.0 lắp ráp. Giải quyết như sau:

  1. Đã thêm gói EF Nuget vào dự án thử nghiệm (được xây dựng dựa trên FW 4.5);
  2. Thêm tham chiếu thủ công vào EntityFramework.dll phiên bản 5 trong dự án Npgsql2010 (Nuget thêm 4.4.0 theo mặc định);
  3. Changed lắp ráp ràng buộc trong Npgsql app.config để "EntityFramework, Version = 5.0.0.0, Culture = trung tính, PublicKeyToken = b77a5c561934e089";
  4. Cố định mô tả ở trên "Constructor cho loại "Npgsql.NpgsqlFactory" không được tìm thấy lỗi bằng cách làm cho nhà xây dựng công cộng;
  5. Cố định lỗi sau "cast Không thể NpgsqlFactory để IDbConnectionFactory" bằng cách thực hiện giao diện IDbConnectionFactory trên NpgsqlFactory:

    sử dụng System.Data.Entity.Infrastructure;
    ...
    public class kín NpgsqlFactory: DbProviderFactory, IServiceProvider, IDbConnectionFactory
    ...
    công DbConnection CreateConnection (string nameOrConnectionString)
    {
    trở lại mới NpgsqlConnection (nameOrConnectionString);
    }
    d

Bây giờ tôi đang gặp "Lỗi: 3F000: schema "dbo" không tồn tại", mà có liên quan đến EF. Tôi có ánh xạ tới lược đồ công khai chuẩn của PostgreSQL trong OnModelCreating: modelBuilder.Entity() của TobContext, mặc dù ToTable ("TableName", "public"). Mong muốn được giải quyết vấn đề này.

+0

Tuyệt vời! Tôi sẽ thêm các phần còn thiếu được báo cáo ngay lập tức: khả năng hiển thị của trình xây dựng và triển khai giao diện. Cảm ơn bạn đã kiểm tra điều đó. –

+1

Tôi nghĩ tôi đã nhảy quá nhanh. Khi kiểm tra tài liệu msdn, tôi nhận thấy rằng SqlClientFactory là một điều và SqlConnectionFactory là một điều khác. NpgsqlFactory tương đương với SqlClientFactory. Để thỏa mãn vấn đề này, chúng ta cần tạo một lớp khác gọi là NpgsqlConnectionFactory, nó sẽ được gắn với sự hỗ trợ của Entity Framework. Xin lỗi vì chuyện đó. Tôi sẽ kiểm tra cách chúng tôi sẽ làm điều đó. –

+0

Tôi đã từ bỏ việc sử dụng EntityFramework với PostgreSQL và Npgsql những vấn đề này được khắc phục. Không có cách nào tôi đi vào sản xuất với điều này cho đến khi nó ổn định hơn. – Jammer

Các vấn đề liên quan