【问题标题】:How to configure ProviderManifestToken for EF Code First如何为 EF Code First 配置 ProviderManifestToken
【发布时间】:2011-06-12 02:34:13
【问题描述】:

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

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

ProviderIncompatibleException:提供者未返回 ProviderManifestToken 字符串

我已阅读有关此的 MS 文档,看来这是 EF 模型生成的 SqlVersion 令牌。问题是我使用的是代码优先方法,所以我没有.edmx 文件,也不知道将元数据信息指向哪里,因为尚未生成数据库。

就数据库名称、用户名和密码而言,我知道我的连接字符串是正确的,因为将它们更改为错误的值会引发预期的错误。不知道从哪里开始。

谢谢。

这是我的连接字符串:

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

【问题讨论】:

  • 您确定使用了连接字符串吗?它应该与从 DbContext 派生的类同名。
  • 是的。我发现了问题所在。这是几件事。 (1)SqlServer中不应该预先创建db,即使它是空的。让英孚做这件事。 (2) 如果未在 DbContext 中声明,则应包含初始目录名称。 (3) 我无法在 Medium Trust 下创建数据库。希望这对某人有所帮助。
  • @nameEquals...你是如何解决上面第 3 项的?

标签: entity-framework connection-string code-first


【解决方案1】:

我在处理MVC3 tutorial on ASP.NET 时遇到了这个问题。

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

【讨论】:

    【解决方案2】:

    我刚刚遇到了这个确切的问题,但我追查到我的 SQL Server 服务没有运行。我刚刚重新启动了我的计算机,通常它会自行启动,但由于某种原因没有。

    【讨论】:

    • 这里也一样。我刚刚检查了我的 Sql Server 配置管理器,但由于某种原因,Sql Server 服务没有运行。一旦我启动该服务,它就可以完美运行
    • 对我来说也是一样,但我的 SQLEXPRESS 服务没有运行。它不适用于正在运行的普通 SQL Server。
    【解决方案3】:

    我发现,当我提供明确的“用户 ID=abcUser;密码=somePwd;”在我的连接字符串中,我能够解决相同的错误。早些时候,我使用“Trusted_Connection=true;”,它允许我调试我的 Web 项目,但在我添加 Windows azure 项目和在将我的 Web 项目添加为 Web 角色后尝试调试 Azure 项目。

    希望对遇到类似情况的人有所帮助。

    谢谢, 维韦克·巴尔

    【讨论】:

      【解决方案4】:

      更改为 Data Source=localhost 对我也有用,也使用 MS SQL 2008 R2 Express

      【讨论】:

        【解决方案5】:

        事实证明这对我很有帮助:

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

        【讨论】:

        • 您的连接字符串中的哪些内容已被证明有帮助?我看不出它有什么独特之处。
        【解决方案6】:

        就我而言,我的连接字符串名称必须与上下文类名称匹配。

        连接字符串:

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

        【讨论】:

          【解决方案7】:

          connectionString 中将数据源更改为localhost 解决了我的问题。

          【讨论】:

            【解决方案8】:

            经过数小时的搜索和摆弄,我找到了一种方法。原来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);
            }
            

            显然这需要进行一些重组(例如缓存已编译的模型,这样您就不需要在每次创建上下文时都重新构建它)。

            对我来说,这完全解决了问题。尽情享受吧!

            【讨论】:

            • 很好——终于有人回答了帖子标题中的问题!!
            • 对于那些使用必须附加到多个 SQL 实例的应用程序的用户,我已经确认此解决方案在连接到多个 SQL 版本(2005 和 2008)时有效。
            • 很好 - 我希望我以前见过这个!看看如何在 EF 6 中更轻松地做到这一点 - 请参阅下面的答案。
            【解决方案9】:

            如果您使用的是 EF 6(刚刚发布),您还有其他选择。

            依赖解析

            您可以使用新的dependency resolution 功能来注册IManifestTokenResolver 的实现(在this preview documentation 中描述为IManifestTokenService)。

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

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

            此示例在为 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);
                    }
                }
            }
            

            【讨论】:

            • 在没有实际连接到数据库的情况下使用 EF 和 ODP.NET 是否有必要这样做?
            • @ObliviousSage 我从未在 Oracle 中使用过 EF,但从this article 看来,您确实需要这样做。文章作者发现“11g”在他的案例中是合适的代币值。
            【解决方案10】:

            我在上面看到了一些关于 oracle 的 cmets,所以这里是针对 oracle 调整的“EntityFrameworkDbConfiguration”的代码:

            internal sealed class EntityFrameworkDbConfiguration : DbConfiguration
            {
                /// <summary>
                /// Initializes a new instance of the <see cref="EntityFrameworkDbConfiguration"/> class.
                /// </summary>
                public EntityFrameworkDbConfiguration()
                {
                    this.AddDependencyResolver(Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices.Instance);
                }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-11-30
              • 2011-08-23
              • 1970-01-01
              • 2016-12-21
              • 2013-08-10
              • 2011-11-04
              相关资源
              最近更新 更多