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>
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);
}
}
}
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!
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.
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; }
}
}
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
passer à source de données=localhost travaillé pour moi aussi en utilisant MS SQL 2008 R2 Express
changer la Source de données en localhost
dans le connectionString
résolu mon problème.
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é.
cela s'est avéré utile pour moi:
<connectionString="Data Source=WORKSTATION\SQLEXPRESS;Initial Catalog=CodeFirst;User ID=CodeFirst_user;Password=********"/>
</connectionStrings>