如何为EF Code First配置ProviderManifestToken

tre*_*orc 41 entity-framework connection-string code-first

我有一个使用EF代码优先的asp.net MVC3项目.对于我的单元测试,我一直在使用SQL Server CE 4.0和SQL Server 2008 Express.两者都与EF一起完美地生成了我的数据库.

但是,当我在单元测试之外运行我的应用程序并将其指向我的连接字符串时,我得到了错误

ProviderIncompatibleException:提供程序未返回ProviderManifestToken字符串

我已经阅读了关于此的MS文档,看起来这是SqlVersionEF模型生成的标记.问题是我使用代码第一种方法,所以我没有.edmx文件,也不知道在哪里指向我的元数据信息,因为还没有生成数据库.

我知道我的连接字符串,因为db name,username和pass是正确的,因为将它们更改为错误的值会引发预期的错误.不知道从哪里开始.

谢谢.

这是我的连接字符串:

<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>
Run Code Online (Sandbox Code Playgroud)

Oll*_*lly 12

如果您使用的是EF 6(刚刚发布),您可以选择其他产品.

依赖性解决方案

您可以使用新的依赖项解析功能来注册IManifestTokenResolver(在此预览文档中描述为IManifestTokenService)的实现.

本文提供了有关如何使用的更多信息DbConfiguration.最简单的使用方法是这样的:

DbConfigurationType(typeof(EntityFrameworkDbConfiguration))]
public class MyContextContext : DbContext
{
}
Run Code Online (Sandbox Code Playgroud)

此示例避免在构建SQL 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @ObliviousSage我从未使用EF和Oracle,但是从[本文](http://www.codeproject.com/Tips/524041/Entity-Framework-ProviderManifestToken-not-valid)看起来好像你*做*需要做这样的事情.该文章的作者发现"11g"在他的案例中是适当的代币值. (2认同)

sin*_*law 10

经过几个小时的搜索和摆弄,我找到了一种方法.原来这个DbModelBuilder类采用了DbProviderInfo它的Build方法,所以我使用它而不是依靠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);
}
Run Code Online (Sandbox Code Playgroud)

显然,这需要一些重组(例如,缓存已编译的模型,因此每次创建上下文时都不需要重新构建它).

对我来说,这完全解决了这个问题.请享用!


Bru*_*ard 6

我刚刚遇到了这个确切的问题,但我追溯到我的SQL Server服务没有运行.我刚刚重启了我的电脑,通常它是自己启动的,但不是出于某种原因.


asa*_*a89 6

在我的例子中,我的连接字符串名称必须与上下文类名称匹配.

连接字符串:

<connectionStrings>
  <add name="NunuContext" connectionString="Data Source=|DataDirectory|Nunu.sdf" providerName="System.Data.SqlServerCe.4.0" />
</connectionStrings>
Run Code Online (Sandbox Code Playgroud)

上下文类:

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; }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 1

我在学习ASP.NET 上的 MVC3 教程时遇到了这个问题。

我的解决方案最终是使用(localhost)命名数据源而不是。这在我的机器上运行良好,适合本地开发工作,但如果数据库位于单独的服务器上,则无济于事。