How to configure ProviderManifestToken for EF Code

2019-01-05 03:41发布

I have a asp.net MVC3 project using EF code-first. For my unit testing I have been using SQL Server CE 4.0 and SQL Server 2008 Express. Both have worked perfectly with EF generating my database as expected.

However, when I run my application outside of a unit test and point it at my connection strings I get the error

ProviderIncompatibleException: The provider did not return a ProviderManifestToken string

I have read the MS documentation on this and it appears this is a SqlVersion token that the EF model generates. The problem is that I am using the code first approach so I have no .edmx file nor do I know where to point my metadata info to because the db hasn't been generated yet.

I know my connection strings as far as db name, username, and pass are correct because changing them to wrong values throws the expected error. Not sure where to begin.

Thanks.

Here is my connection 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>

9条回答
孤傲高冷的网名
2楼-- · 2019-01-05 04:07

I just had this exact problem but I traced it down to my SQL Server service wasn't running. I had just restarted my computer and usually it starts on it's own but didn't for some reason.

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-01-05 04:14

Changing to Data Source=localhost worked for me also using MS SQL 2008 R2 Express

查看更多
对你真心纯属浪费
4楼-- · 2019-01-05 04:14

Changing the Data Source to localhost in the connectionString solved my problem.

查看更多
孤傲高冷的网名
5楼-- · 2019-01-05 04:15

I found, when i provided explicit "User Id=abcUser; Password=somePwd;" in my connection string i am able to resolve the same error. Earlier i was using the "Trusted_Connection=true;", which allowed me to debug my web project, but started giving me error - {"The provider did not return a ProviderManifestToken string."} as soon as i added the Windows azure project and tried debugging the Azure project after adding my web project as a web role under it.

Hope it helps some one experiencing a similar situation.

Thanks, Vivek Bahl

查看更多
爷的心禁止访问
6楼-- · 2019-01-05 04:18

In my case, my connection string name must match the context class name.

Connection String:

<connectionStrings>
  <add name="NunuContext" connectionString="Data Source=|DataDirectory|Nunu.sdf" providerName="System.Data.SqlServerCe.4.0" />
</connectionStrings>

Context Class:

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楼-- · 2019-01-05 04:20

After hours of searching & fiddling, I found a way to do it. Turns out the DbModelBuilder class takes a DbProviderInfo in its Build method, so I use that instead of relying on EF to call 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);
}

Obviously this needs some reorganization (e.g. cache the compiled model so you don't need to re-build it every time a context is created).

For me this completely solved the problem. Enjoy!

查看更多
登录 后发表回答