it-swarm.com.de

So konfigurieren Sie ProviderManifestToken für EF-Code zuerst

Ich habe ein asp.net MVC3-Projekt mit EF-Code-first. Für meine Unit-Tests habe ich SQL Server CE 4.0 und SQL Server 2008 Express verwendet. Beide haben perfekt mit EF zusammengearbeitet, wie erwartet, meine Datenbank zu generieren.

Wenn ich jedoch meine Anwendung außerhalb eines Komponententests ausführen und auf meine Verbindungszeichenfolgen verweise, erhalte ich den Fehler 

ProviderIncompatibleException: Der Provider hat keine ProviderManifestToken-Zeichenfolge zurückgegeben

Ich habe die MS-Dokumentation dazu gelesen und es scheint, dass dies ein SqlVersion-Token ist, das das EF-Modell generiert. Das Problem ist, dass ich den Code-First-Ansatz verwende, also keine .edmx-Datei habe und ich nicht weiß, wohin meine Metadaten-Informationen zeigen sollen, da die Datenbank noch nicht generiert wurde.

Ich kenne meine Verbindungszeichenfolgen, soweit Datenbankname, Benutzername und Weiterleiten korrekt sind, da der erwartete Fehler durch das Ändern dieser Werte in falsche Werte ausgelöst wird. Nicht sicher, wo ich anfangen soll.

Vielen Dank.

Hier ist meine Verbindungszeichenfolge:

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

Wenn Sie EF 6 (soeben veröffentlicht) verwenden, haben Sie eine Alternative.

Abhängigkeitsauflösung

Mit der neuen Funktion Abhängigkeitsauflösung können Sie eine Implementierung von IManifestTokenResolver registrieren (beschrieben in dieser Vorschaudokumentation als IManifestTokenService). 

Dieser Artikel enthält etwas mehr Informationen zur Verwendung von DbConfiguration. Der einfachste Weg, es zu benutzen, ist wie folgt:

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

In diesem Beispiel wird beim Erstellen der Metadaten für SQL Server-Verbindungen jede Reise zur Datenbank vermieden und die Kompatibilität mit SQL Server 2005 wird automatisch angegeben.

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);
        }
    }
}
12
Olly

Nach stundenlangem Suchen und Fummeln fand ich einen Weg, es zu tun. Stellt sich heraus, dass die DbModelBuilder-Klasse eine DbProviderInfo in ihrer Build-Methode verwendet, so benutze ich das, anstatt auf EF zu setzen, um OnModelCreated aufzurufen:

// '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);
}

Offensichtlich muss dazu eine Reorganisation durchgeführt werden (z. B. das kompilierte Modell zwischenspeichern, damit Sie es nicht jedes Mal neu erstellen müssen, wenn ein Kontext erstellt wird).

Für mich hat dies das Problem vollständig gelöst. Genießen!

10
sinelaw

In meinem Fall muss der Name der Verbindungszeichenfolge mit dem Namen der Kontextklasse übereinstimmen.

Verbindungszeichenfolge:

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

Kontextklasse:

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; }
    }
}
6
asakura89

Ich hatte genau dieses Problem, aber ich habe es darauf zurückgeführt, dass mein SQL Server-Dienst nicht ausgeführt wurde. Ich hatte gerade meinen Computer neu gestartet und normalerweise startet er von alleine, aber aus irgendeinem Grund nicht.

6
Bruce Hubbard

Das Ändern der Datenquelle in localhost in der connectionString hat mein Problem gelöst. 

1
Bala

Wechsel zu Data Source = localhost funktionierte für mich auch mit MS SQL 2008 R2 Express

1
John

Ich hatte dieses Problem beim Durcharbeiten des MVC3-Tutorials unter ASP.NET

Meine Lösung endete damit, (localhost) anstelle einer benannten Datenquelle zu verwenden. Dies funktioniert gut auf meiner Box, für lokale Entwicklerarbeit, würde aber nicht helfen, wenn die Datenbank auf einem separaten Server wäre. 

1
Cameron Combs

Ich habe festgestellt, als ich explizit angegeben habe: "User Id = abcUser; Password = somePwd;" In meiner Verbindungszeichenfolge kann ich den gleichen Fehler beheben. Früher habe ich "Trusted_Connection = true;" verwendet, was mir erlaubt, mein Webprojekt zu debuggen, gab jedoch einen Fehler an - {"Der Provider hat keine ProviderManifestToken-Zeichenfolge zurückgegeben."}, Sobald ich das Windows Azure-Projekt hinzugefügt habe habe versucht, das Azure-Projekt zu debuggen, nachdem ich mein Webprojekt als Webrolle hinzugefügt hatte. 

Ich hoffe, es hilft jemandem, der eine ähnliche Situation erlebt.

Danke, Vivek Bahl

1
Vivek Bahl

Das hat sich für mich als hilfreich erwiesen:

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