Comment configurer ProviderManifestToken pour le code EF en premier

j'ai un asp.net projet MVC3 utilisant D'abord le code EF. Pour mes tests unitaires, J'ai utilisé SQL Server CE 4.0 et SQL Server 2008 Express. Les deux ont parfaitement fonctionné avec EF générant ma base de données comme prévu.

cependant, lorsque j'exécute mon application en dehors d'un test unitaire et que je la pointe sur mes chaînes de connexion, j'obtiens l'erreur

ProviderIncompatibleException: le fournisseur N'a pas retourné une chaîne de caractères ProviderManifestToken

j'ai lu la documentation MS à ce sujet et il semble qu'il s'agisse d'un jeton SqlVersion que le modèle EF génère. Le problème est que j'utilise la première approche du code donc je n'ai pas de fichier .edmx et je ne sais pas où pointer mes informations de métadonnées parce que la base de données n'a pas encore été générée.

je sais que mes chaînes de connexion aussi loin que le nom de la base de données, le nom d'utilisateur et le pass sont corrects parce que les changer en mauvaises valeurs jette l'attendu erreur. Vous ne savez pas où commencer.

Merci.

voici ma chaîne de connexion:

<connectionStrings>
  <add
    name="SqlConnection"
    providerName="System.Data.SqlClient"
    connectionString="Data Source=WORKSTATIONSQLEXPRESS;Initial Catalog=CodeFirst;Integrated Security=False;
    Persist Security Info=False;User ID=CodeFirst_user;Password=password1;Connect Timeout=120;MultipleActiveResultSets=True;"/>
</connectionStrings>
41
demandé sur marc_s 2011-01-20 01:23:22

9 réponses

si vous utilisez EF 6 (vient de sortir) vous avez une alternative.

Résolution De Dépendance

vous pouvez utiliser la nouvelle fonction dependency resolution pour enregistrer une implémentation de IManifestTokenResolver (décrit dans cette documentation de prévisualisation comme IManifestTokenService ).

Cet article donne un peu plus d'informations sur la façon d'utiliser DbConfiguration . Le facile d'utilisation, il est comme ceci:

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

cet exemple évite tout déplacement vers la base de données lors de la construction des métadonnées pour les connexions SQL Server, et spécifie automatiquement la compatibilité SQL Server 2005.

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);
        }
    }
}
11
répondu Olly 2013-10-22 00:47:47

après des heures de recherche et de bricolage, j'ai trouvé un moyen de le faire. Il s'avère que la classe DbModelBuilder prend un DbProviderInfo dans sa méthode Build , donc je l'utilise au lieu de compter sur EF pour appeler 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);
}

cela nécessite évidemment une réorganisation (par exemple, mettre en cache le modèle compilé pour que vous n'ayez pas besoin de le reconstruire à chaque fois qu'un contexte est créé).

Pour moi, cela a complètement résolu le problème. Profitez-en!

9
répondu sinelaw 2012-08-21 18:03:43

je viens d'avoir ce problème exact mais je l'ai tracé jusqu'à mon service de serveur SQL n'était pas en cours d'exécution. Je venais de redémarrer mon ordinateur et d'habitude, il démarre tout seul, mais je ne l'ai pas fait pour une raison quelconque.

6
répondu Bruce Hubbard 2011-05-10 14:12:59

dans mon cas, mon nom de chaîne de connexion doit correspondre au nom de la classe de contexte.

Chaîne De Connexion:

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

Contexte De La 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; }
    }
}
6
répondu asakura89 2012-04-27 22:24:25

j'ai trouvé, lorsque j'ai fourni explicitement" User Id=abuser; Password=somePwd; " dans ma chaîne de connexion je suis capable de résoudre la même erreur. Plus tôt, j'utilisais " Trusted_Connection=true;", ce qui m'a permis de déboguer mon projet web, mais a commencé à me donner une erreur - {"le fournisseur n'a pas retourné une chaîne ProviderManifestToken."} dès que J'ai ajouté le projet Windows azure et essayé de déboguer le projet Azure après avoir ajouté mon projet web comme un rôle web sous elle.

espérons que cela aide quelqu'un qui vit une situation similaire.

Merci, Vivek Bahl

1
répondu Vivek Bahl 2011-11-07 06:12:57

passer à source de données=localhost travaillé pour moi aussi en utilisant MS SQL 2008 R2 Express

1
répondu John 2011-12-26 05:16:54

changer la Source de données en localhost dans le connectionString résolu mon problème.

1
répondu Bala 2012-10-20 03:54:05

j'ai eu ce problème en travaillant sur le tutoriel MVC3 sur ASP.NET .

ma solution a fini par être d'utiliser (localhost) au lieu d'une source de données nommée. Cela fonctionne très bien sur ma boîte, pour le travail de dev local, mais ne serait pas utile si la base de données était sur un serveur séparé.

1
répondu Cameron Combs 2013-02-28 08:07:05

cela s'est avéré utile pour moi:

<connectionString="Data Source=WORKSTATION\SQLEXPRESS;Initial Catalog=CodeFirst;User ID=CodeFirst_user;Password=********"/> 
</connectionStrings> 
0
répondu andrew 2012-10-29 17:23:04