2011-01-19 45 views
41

我有一個使用EF代碼優先的asp.net MVC3項目。對於我的單元測試,我一直使用SQL Server CE 4.0和SQL Server 2008 Express。兩者都可以很好地與EF生成預期的數據庫。如何爲EF代碼優先配置ProviderManifestToken

然而,當我跑我的應用程序單元測試之外,在我的連接字符串指向它,我得到的錯誤

ProviderIncompatibleException:提供者未返回ProviderManifestToken串

我已經閱讀了MS的文檔,看起來這是EF模型生成的一個SqlVersion令牌。問題是我正在使用代碼第一種方法,所以我沒有.edmx文件,也不知道在哪裏指向我的元數據信息,因爲數據庫尚未生成。

我知道我的連接字符串只要db名稱,用戶名和傳遞都是正確的,因爲將它們更改爲錯誤的值會引發預期的錯誤。不知道從哪裏開始。

謝謝。

這裏是我的連接字符串:

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

您確定使用了連接字符串嗎?它應該和從DbContext派生的類具有相同的名稱。 – 2011-01-19 22:36:43

+9

就是這樣。我發現問題是什麼。這是幾件事情。 (1)即使數據庫爲空,也不應在SqlServer中預先創建數據庫。讓EF做到這一點。 (2)如果未在DbContext中聲明,則應包含初始目錄名稱。 (3)我無法在Medium Trust下創建數據庫。希望這可以幫助某人。 – trevorc 2011-01-19 23:12:41

+1

@nameEquals ...你是如何解決上述第3項的? – 2011-05-09 22:51:01

回答

1

通過MVC3 tutorial on ASP.NET工作時,我有這個問題。

我的解決方案最終是使用(localhost)而不是指定的數據源。這工作正常,在我的盒子上,爲本地開發工作,但沒有幫助,如果數據庫在一個單獨的服務器上。

6

我只是有這個確切的問題,但我追溯到我的SQL Server服務沒有運行。我剛剛重新啓動了電腦,通常是自行啓動,但沒有出於某種原因。

+0

同樣在這裏。我剛剛檢查了我的Sql Server配置管理器,並且Sql Server服務由於某種原因未運行。一旦我開始服務,它的工作完美 – 2011-06-05 18:27:19

1

我發現,當我提供明確的「User Id = abcUser; Password = somePwd;」在我的連接字符串中,我能夠解決相同的錯誤。之前我使用的是「Trusted_Connection = true;」,它允許我調試我的web項目,但開始給我錯誤 - {「提供程序沒有返回ProviderManifestToken字符串。」}一旦我添加了Windows Azure項目和嘗試在將我的Web項目添加爲Web項目之後調試Azure項目。

希望它有助於一些人遇到類似的情況。

感謝, 維韋克巴爾

1

更改爲數據源=本地主機工作對我來說也使用MS SQL 2008 R2快速

0

這已經被證明有助於我:

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

更改數據源localhostconnectionString解決我的問題。

9

經過數小時的搜索&擺弄,我找到了一個辦法。原來,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); 
} 

顯然,這需要一些重組(例如高速緩存中的編譯模型,所以你不需要每次創建上下文時重新構建它)。

對我來說,這完全解決了這個問題。請享用!

9

如果您使用的是EF 6(剛剛發佈),您可以選擇另一種方法。

解決依賴

您可以使用dependency resolution新的功能註冊的IManifestTokenResolver的實現(如this preview documentation描述IManifestTokenService)。

This article給出了一些關於如何使用DbConfiguration的更多信息。使用它最簡單的方法是這樣的:建立一個SQL Server連接的元數據時

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

這個例子避免了訪問數據庫,並自動指定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); 
     } 
    } 
}