2013-02-04 10 views
9

Sto cercando di ottenere il codice EF 5.0 prima lavorando con PostgreSQL (provider Npgsql). Ho installato Npgsql 2.0.12.1 tramite NuGet (tuttavia l'assembly di riferimento è 2.0.12.0). Ho Npgsql dichiarata in app.config (sia in fabbrica e la fabbrica di connessione predefinito provider):Entity Framework 5.0 PostgreSQL (Npgsql) factory di connessione predefinita

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

Ho seguente test in esecuzione con successo:

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

Ciò significa che almeno istanza di database è in esecuzione e fornitore è configurato con successo. Ora quello che voglio è quello di utilizzare contesto database personalizzato ereditato dal DbContext che sarà legata al provider stesso e inizializzata tramite stringa di connessione:

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

seguente test ha esito negativo:

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

Si dice

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. 

L'eccezione interna è InvalidOperationException:

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

Credo che ci sia un problema con la stringa di connessione (non contiene fornitore Npgsql):

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

Qual è il modo più elegante per risolvere questo problema a livello di codice? Ho appena provato a passare connectionString da app.config al costruttore del contesto, funziona.
modificare
progetto di test Caricati a Dropbox - VS2012 solution, 10 mb

+0

Ciao! Quest'ultimo .1 nel pacchetto nuget è perché non ho potuto aggiornare il pacchetto 2.0.12. C'era un file mancante nel pacchetto e ho dovuto aggiornarlo. Ma state certi che il file binario di Npgsql è lo stesso della versione 2.0.12. :) Ti dispiacerebbe mandarmi questo esempio di progetto in modo che possa dargli un'occhiata? Penso che questo potrebbe essere un bug in Npgsql che potrebbe mancare a un costruttore che EF si aspetta. La mia email è francisco su npgsql dor org. Grazie in anticipo. –

+0

La versione non è un problema, anche se ho perso un po 'di tempo per scoprire perché l'assembly non è stato trovato durante il runtime. Il punto è veramente nella configurazione delle stringhe di connessione, specialmente nel fatto che nel mio ambiente di produzione non posso usare/modificare i file .config (applicazione XBAP di WPF pubblicata nei limiti di IIS). Vi invierà un progetto di esempio in poche ore. – Jaded

+0

Inviato progetto di esempio, aggiunto il collegamento per il download di Dropbox se qualcun altro vuole guardare. – Jaded

risposta

7

Dug più a fondo il problema, ha scoperto che essa è causata da quel fatto che Npgsql fa riferimento EntityFramework 4.4.0 assemblaggio. Risolto come segue:

  1. Aggiunto il pacchetto EF Nuget per testare il progetto (che è costruito contro FW 4.5);
  2. Riferimento aggiunto manualmente a EntityFramework.dll versione 5 nel progetto Npgsql2010 (Nuget aggiunge 4.4.0 per impostazione predefinita);
  3. Modificato complesso vincolante Npgsql app.config per "EntityFramework, Version = 5.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089";
  4. fisse di cui sopra "Costruttore per tipo 'Npgsql.NpgsqlFactory' non viene trovato errore rendendo costruttore pubblico;
  5. seguente errore fisso 'Cast impossibile NpgsqlFactory a IDbConnectionFactory' implementando interfaccia IDbConnectionFactory su NpgsqlFactory:

    utilizzando System.Data.Entity.Infrastructure;
    ...
    pubblico classe chiusa NpgsqlFactory: DbProviderFactory, IServiceProvider, IDbConnectionFactory
    ...
    pubblico DbConnection CreateConnection (stringa nameOrConnectionString)
    {
    ritorno nuova NpgsqlConnection (nameOrConnectionString);
    }
    d

Ora sto vivendo "Errore: 3F000: schema "dbo" non esiste", che è legato alla EF. Ho mappato lo schema pubblico standard di PostgreSQL in OnModelCreating di DbContext: modelBuilder.Entity(). ToTable ("TableName", "public") però. In attesa di soluzione di questo problema.

+0

Ottimo! Aggiungerò subito i pezzi mancanti segnalati: visibilità del costruttore e implementazione dell'interfaccia. Grazie per averlo controllato. –

+1

Penso di aver saltato troppo in fretta. Durante la verifica della documentazione di msdn, ho notato che SqlClientFactory è una cosa e SqlConnectionFactory è un'altra. NpgsqlFactory è l'equivalente di SqlClientFactory. Per soddisfare questo problema, dobbiamo creare un'altra classe chiamata NpgsqlConnectionFactory che sarà associata al supporto di Entity Framework. Perdonami per quello. Controllerò come lo faremo. –

+0

Ho rinunciato a usare EntityFramework con PostgreSQL e Npgsql questi problemi sono stati risolti. In nessun modo entrerò in produzione con questo fino a quando non sarà più stabile. – Jammer

Problemi correlati