如何为EF代码优先configurationProviderManifestToken
我有一个使用EF代码优先的asp.net MVC3项目。 对于我的unit testing,我一直在使用SQL Server CE 4.0和SQL Server 2008 Express。 EF和预期一样完美地生成了我的数据库。
但是,当我在unit testing之外运行我的应用程序并将其指向我的连接string时,出现错误
ProviderIncompatibleException:提供程序没有返回ProviderManifestTokenstring
我已经阅读了MS文档,看起来这是EF模型生成的SqlVersion
标记。 问题是我正在使用代码的第一种方法,所以我没有.edmx
文件,也不知道在哪里指出我的元数据信息,因为数据库尚未生成。
我知道我的连接string只要db名称,用户名和传递是正确的,因为将它们更改为错误的值将引发预期的错误。 不知道从哪里开始。
谢谢。
这是我的连接string:
<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>
经过几个小时的search和摆弄,我find了一个办法。 原来DbModelBuilder
类在它的Build
方法中使用了DbProviderInfo
,所以我使用它来代替依靠EF来调用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); }
显然,这需要重新组织(例如caching已编译的模型,所以每次创build上下文时都不需要重新构build它)。
对我来说,这完全解决了这个问题。 请享用!
如果您使用EF 6(刚刚发布),您可以select一个。
依赖决议
您可以使用新的依赖关系parsingfunction来注册IManifestTokenResolver
的实现(在本预览文档中以IManifestTokenService
的IManifestTokenResolver
描述)。
本文给出了一些关于如何使用DbConfiguration
更多信息。 最简单的使用方法是这样的:
DbConfigurationType(typeof(EntityFrameworkDbConfiguration))] public class MyContextContext : DbContext { }
此示例避免了在构buildSQL Server连接的元数据时出现任何数据库行为,并自动指定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); } } }
我只是有这个确切的问题,但我追溯到我的SQL Server服务没有运行。 我刚刚重新启动了电脑,通常是自行启动,但没有出于某种原因。
在我的情况下,我的连接string名称必须匹配上下文类名称。
连接string:
<connectionStrings> <add name="NunuContext" connectionString="Data Source=|DataDirectory|Nunu.sdf" providerName="System.Data.SqlServerCe.4.0" /> </connectionStrings>
上下文类:
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; } } }
我发现,当我提供明确的“User Id = abcUser; Password = somePwd;” 在我的连接string我能够解决同样的错误。 早些时候,我使用“Trusted_Connection = true;”,它允许我debugging我的Web项目,但开始给我错误 – {“提供程序没有返回一个ProviderManifestTokenstring。”}一旦我添加Windows Azure项目和在将我的Web项目添加为Web项目之后,尝试debuggingAzure项目。
希望它能帮助一个遇到类似情况的人。
谢谢,Vivek Bahl
更改为数据源= localhost为我也使用MS SQL 2008 R2 Express
在connectionString
中将数据源更改为localhost
解决了我的问题。
在处理ASP.NET上的MVC3教程时,我遇到了这个问题。
我的解决scheme最终是使用(localhost)
而不是一个指定的数据源。 这工作正常,我的盒子,本地开发工作,但不会帮助,如果数据库是在一个单独的服务器上。
这已经certificate对我有帮助:
<connectionString="Data Source=WORKSTATION\SQLEXPRESS;Initial Catalog=CodeFirst;User ID=CodeFirst_user;Password=********"/> </connectionStrings>