2011-01-19 17 views
41

Ho un progetto MV3 di asp.net utilizzando il codice EF prima. Per il mio test delle unità ho utilizzato SQL Server CE 4.0 e SQL Server 2008 Express. Entrambi hanno funzionato perfettamente con EF generando il mio database come previsto.Come configurare ProviderManifestToken per il codice EF First

Tuttavia, quando faccio funzionare la mia applicazione al di fuori di un test di unità e di puntarlo verso il mio stringhe di connessione ottengo l'errore

ProviderIncompatibleException: Il provider non ha restituito una stringa ProviderManifestToken

I Ho letto la documentazione MS su questo e sembra che questo sia un token SqlVersion generato dal modello EF. Il problema è che sto usando il primo approccio al codice, quindi non ho il file .edmx né so dove indirizzare le informazioni sui metadati perché il db non è ancora stato generato.

So che le mie stringhe di connessione per quanto riguarda il nome db, il nome utente e il pass sono corretti perché la loro modifica in valori errati genera l'errore previsto. Non so da dove cominciare.

Grazie.

Qui è la mia stringa di connessione:

<connectionStrings> 
    <add 
    name="SqlConnection" 
    providerName="System.Data.SqlClient" 
    connectionString="Data Source=WORKSTATION\SQLEXPRESS;Initial Catalog=CodeFirst;Integrated Security=False; 
    Persist Security Info=False;User ID=CodeFirst_user;Password=password1;Connect Timeout=120;MultipleActiveResultSets=True;"/> 
</connectionStrings> 
+5

Sei sicuro che la stringa di connessione sia utilizzata? Dovrebbe avere lo stesso nome della classe derivata da DbContext. –

+9

Lo è. Ho trovato qual è il problema. Erano un paio di cose. (1) Il db non dovrebbe essere pre-creato in SqlServer anche se è vuoto. Lascia che EF faccia questo. (2) Dovrebbe essere incluso un nome di catalogo iniziale se non è dichiarato in DbContext. (3) Non riesco a creare il db in Medium Trust. Spero che questo aiuti qualcuno. – trevorc

+1

@nameEquals ... come hai risolto l'articolo 3 sopra? –

risposta

1

Ho avuto questo problema quando si lavora attraverso il MVC3 tutorial on ASP.NET.

La mia soluzione ha finito per utilizzare (localhost) invece di un'origine dati denominata. Funziona bene sulla mia scatola, per lavoro di sviluppo locale, ma non sarebbe di aiuto se il database fosse su un server separato.

6

Ho appena avuto questo problema esatto ma l'ho tracciato fino al mio servizio SQL Server non era in esecuzione. Avevo appena riavviato il mio computer e di solito inizia da solo, ma non per qualche motivo.

+0

Lo stesso qui. Ho appena controllato il mio Sql Server Configuration Manager e il servizio Sql Server non era in esecuzione per qualche motivo. Una volta iniziato il servizio ha funzionato perfettamente –

+0

La stessa cosa per me, ma il mio servizio SQLEXPRESS non era in esecuzione. Non funzionava con il normale SQL Server in esecuzione. – Pieter

1

Ho trovato, quando ho fornito esplicito "User Id = abcUser; Password = somePwd;" nella mia stringa di connessione sono in grado di risolvere lo stesso errore. In precedenza stavo usando "Trusted_Connection = true;", che mi permetteva di eseguire il debug del mio progetto web, ma ha iniziato a darmi un errore - {"Il provider non ha restituito una stringa ProviderManifestToken."} Non appena ho aggiunto il progetto azzurro di Windows e ha provato a eseguire il debug del progetto di Azure dopo aver aggiunto il mio progetto Web come ruolo Web al di sotto di esso.

Spero che qualcuno possa sperimentare una situazione simile.

Grazie, Vivek Bahl

1

Passaggio a Data Source = localhost ha lavorato per me anche utilizzando MS SQL 2008 R2 espresso

0

Questo ha dimostrato utile per me:

<connectionString="Data Source=WORKSTATION\SQLEXPRESS;Initial Catalog=CodeFirst;User ID=CodeFirst_user;Password=********"/> 
</connectionStrings> 
6

In Nel mio caso, il nome della stringa di connessione deve corrispondere al nome della classe di contesto.

stringa di connessione:

<connectionStrings> 
    <add name="NunuContext" connectionString="Data Source=|DataDirectory|Nunu.sdf" providerName="System.Data.SqlServerCe.4.0" /> 
</connectionStrings> 

Contesto Classe:

using System.Data.Entity; 
namespace Nunu.Models 
{ 
    public class NunuContext : DbContext 
    { 
     System.Data.Entity.DropCreateDatabaseIfModelChanges<Nunu.Models.NunuContext>()); 

     public DbSet<Nunu.Models.NunuFirst> NunuFirsts { get; set; } 

     public DbSet<Nunu.Models.NunuLast> NunuLasts { get; set; } 
    } 
} 
1

Modificare l'origine dati per localhost nel connectionString risolto il mio problema.

9

Dopo ore di ricerca & giocherellare, ho trovato un modo per farlo. Si scopre che la classe DbModelBuilder prende un DbProviderInfo nel suo metodo Build, per cui uso che, invece di basarsi su EF chiamare OnModelCreated:

// 'Entities' is my DbContext subclass, the "container" in EF terms. 
public static Entities GetNewContext() 
{ 
    // Get a connection, for example: 
    var connection = new SqlConnection(GetConnectionString()); 

    // Create a DbModelBuilder 
    var modelBuilder = new DbModelBuilder(); 
    // Configure the model builder. 
    // I changed my DbContext subclass - added a public version of OnModelCreated and called it ConfigureModelBuilder 
    Entities.ConfigureModelBuilder(modelBuilder); 

    // Here's where the magic happens. 
    // Build the model and pass the ProviderManifestToken (I use 2005 to avoid a bug in precision of sql datetime columns when using concurrency control) 
    var model = modelBuilder.Build(new System.Data.Entity.Infrastructure.DbProviderInfo("System.Data.SqlClient", "2005")); 
    // Compile the model 
    var compiledModel = model.Compile(); 

    // Create the container (DbContext subclass). Ideally all the previous stuff should be cached. 
    return new Entities(connection, compiledModel, true); 
} 

Ovviamente questo ha bisogno di un po 'di riorganizzazione (ad esempio la cache del modello compilato in modo non è necessario ricostruirlo ogni volta che viene creato un contesto).

Per me questo ha completamente risolto il problema. Godere!

+1

Nice- qualcuno finalmente ha risposto alla domanda dal titolo del post !! – Shawson

+0

Per coloro che lavorano con app che devono collegarsi a più istanze SQL, ho confermato che questa soluzione funziona quando ci si connette a più versioni SQL (2005 e 2008). – RMart

+0

Nice - Vorrei averlo visto prima! Dai un'occhiata a come puoi farlo un po 'più facilmente in EF 6 - vedi la mia risposta qui sotto. – Olly

9

Se si utilizza EF 6 (appena rilasciato) si ha un'alternativa.

Dipendenza Risoluzione

È possibile utilizzare la nuova funzione dependency resolution registrare un'implementazione di IManifestTokenResolver (descritto nel this preview documentation come IManifestTokenService).

This article fornisce ulteriori informazioni su come utilizzare DbConfiguration. Il modo più semplice da usare, è come questo:

DbConfigurationType(typeof(EntityFrameworkDbConfiguration))] 
public class MyContextContext : DbContext 
{ 
} 

Questo esempio consente di evitare qualsiasi viaggio al database quando si costruisce i metadati per le connessioni SQL Server, e specifica automaticamente SQL Server 2005 compatibilità.

using System.Data.Common; 
using System.Data.Entity; 
using System.Data.Entity.Infrastructure; 
using System.Data.Entity.Infrastructure.DependencyResolution; 
using System.Data.SqlClient; 

/// <summary> 
/// A configuration class for SQL Server that specifies SQL 2005 compatability. 
/// </summary> 
internal sealed class EntityFrameworkDbConfiguration : DbConfiguration 
{ 
    /// <summary> 
    /// The provider manifest token to use for SQL Server. 
    /// </summary> 
    private const string SqlServerManifestToken = @"2005"; 

    /// <summary> 
    /// Initializes a new instance of the <see cref="EntityFrameworkDbConfiguration"/> class. 
    /// </summary> 
    public EntityFrameworkDbConfiguration() 
    { 
     this.AddDependencyResolver(new SingletonDependencyResolver<IManifestTokenResolver>(new ManifestTokenService())); 
    } 

    /// <inheritdoc /> 
    private sealed class ManifestTokenService : IManifestTokenResolver 
    { 
     /// <summary> 
     /// The default token resolver. 
     /// </summary> 
     private static readonly IManifestTokenResolver DefaultManifestTokenResolver = new DefaultManifestTokenResolver(); 

     /// <inheritdoc /> 
     public string ResolveManifestToken(DbConnection connection) 
     { 
      if (connection is SqlConnection) 
      { 
       return SqlServerManifestToken; 
      } 

      return DefaultManifestTokenResolver.ResolveManifestToken(connection); 
     } 
    } 
} 
+0

È necessario qualcosa di simile all'utilizzo di EF con ODP.NET senza effettivamente connettersi al database? –

+2

@ObliviousSage Non ho mai usato EF con Oracle, ma da [questo articolo] (http://www.codeproject.com/Tips/524041/Entity-Framework-ProviderManifestToken-not-valid) sembra che tu * faccia * bisogno di fare qualcosa di simile. L'autore dell'articolo ha scoperto che "11g" era il valore di token appropriato nel suo caso. – Olly

Problemi correlati