2016-11-15 123 views
0

一个棘手的(和令人沮丧的问题) - 也许你们这些人可能是足够聪明来解决它:实体框架6 - Npgsql的 - 连接字符串错误

问题

我希望能够读/使用Entity Frameworks写入我的数据库。我在Heroku上运行了一个简单的应用程序rails(简单的脚手架)。我想连接到这个数据库并操作记录。好消息是,我可以使用npgsql成功连接到该数据库。坏消息是我不能用Entity Frameworks来做。这是我收到的错误:

System.Data.Entity.Core.ProviderIncompatibleException:错误 同时获得由数据库提供信息时发生。此 可能由实体框架使用不正确的连接 字符串引起。检查内部例外以获取详细信息,并确保 连接字符串正确。 ---> System.Data.Entity.Core.ProviderIncompatibleException:提供程序 未返回ProviderManifestToken字符串。 ---> System.IO.FileLoadException:无法加载文件或程序集'Npgsql, 版本= 3.1.2.0,Culture = neutral,PublicKeyToken = 5d8b90d52f46fda7'或 其依赖项之一。找到的程序集清单定义 与程序集引用不匹配。 (异常来自HRESULT: 0x80131040)

这里是堆栈跟踪:

at Npgsql.NpgsqlServices.GetDbProviderManifestToken(DbConnection connection) 
    at System.Data.Entity.Core.Common.DbProviderServices.GetProviderManifestToken(DbConnection connection) 
    --- End of inner exception stack trace --- 
    at System.Data.Entity.Core.Common.DbProviderServices.GetProviderManifestToken(DbConnection connection) 
    at System.Data.Entity.Utilities.DbProviderServicesExtensions.GetProviderManifestTokenChecked(DbProviderServices providerServices, DbConnection connection) 
    --- End of inner exception stack trace --- 
    at System.Data.Entity.Utilities.DbProviderServicesExtensions.GetProviderManifestTokenChecked(DbProviderServices providerServices, DbConnection connection) 
    at System.Data.Entity.Infrastructure.DefaultManifestTokenResolver.<>c__DisplayClass1.<ResolveManifestToken>b__0(Tuple`3 k) 
    at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory) 
    at System.Data.Entity.Infrastructure.DefaultManifestTokenResolver.ResolveManifestToken(DbConnection connection) 
    at System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderInfo(DbConnection connection, DbProviderManifest& providerManifest) 
    at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection) 
    at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext) 
    at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input) 
    at System.Data.Entity.Internal.LazyInternalContext.InitializeContext() 
    at System.Data.Entity.Internal.InternalContext.Initialize() 
    at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) 
    at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() 
    at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext() 
    at System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider() 
    at System.Linq.Queryable.Select[TSource,TResult](IQueryable`1 source, Expression`1 selector) 
    at ge_EntityFrameworkTest.Program.<Test>d__4.MoveNext() in c:\Users\Koshy\Documents\Visual Studio 2013\Projects\Practice\ge-EntityFrameworkTest\ge-EntityFrameworkTest\Program.cs:line 118 

这里是我的连接字符串:

NpgsqlConnectionStringBuilder sqlBuilder = new NpgsqlConnectionStringBuilder(); 
       sqlBuilder.Username = user; 
       sqlBuilder.Password = password; 
       sqlBuilder.Host = host; 
       sqlBuilder.Port = Int32.Parse(port); 
       sqlBuilder.Database = database; 
       sqlBuilder.Pooling = true; 
       sqlBuilder.UseSslStream = true;  
       sqlBuilder.SslMode = Npgsql.SslMode.Require; 
       sqlBuilder.TrustServerCertificate = true; 

这是我的“Hello world”,我用于连接并从我的数据库读取(从玩家表)。它成功地将“Lionel Messi”打印到控制台上。大!

  #region connectingAndReadingDatabase 
      using (var conn = new NpgsqlConnection(sqlBuilder.ToString())) 
      { 
       conn.Open(); 
       using (var cmd = new NpgsqlCommand()) 
       { 
        cmd.Connection = conn; 

        // Retrieve all rows 
        cmd.CommandText = "SELECT * FROM players"; 
        using (var reader = cmd.ExecuteReader()) 
        { 
         while (reader.Read()) 
         { 
          Console.WriteLine(reader.GetString(1)); 
         } 
        } 
       } 
      } 
      #endregion 

问题是当我尝试使用实体框架。它带着痛苦的错误大规模地失败。我使用完全相同的连接字符串,并且不能为我的生活找出我要出错的地方。也许你可能很容易发现问题?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Text.RegularExpressions; 
using System.Threading.Tasks; 
using System.Net.Http; 
using Newtonsoft.Json; 
using Npgsql; 
using System.Data.Entity; 
using System.Data.Common; 
using System.ComponentModel.DataAnnotations.Schema; 
using System.ComponentModel.DataAnnotations; 
using System.Configuration; 
using System.Data.Entity.ModelConfiguration.Conventions; 


// Here is the code pertaining to my hello world entity framework example: 

     [Table("players", Schema = "public")] 
     public class Player 
     { 
      [Key] 
      [Column("id")] 
      public int id { get; set; } 
      [Column("name")] 
      public string Name { get; set; } 
      [Column("team")] 
      public string Team { get; set; } 
      public Player() { } 
     } 

     class NpgsqlConfiguration : System.Data.Entity.DbConfiguration 
     { 
      public NpgsqlConfiguration() 
      { 
       SetProviderServices ("Npgsql", Npgsql.NpgsqlServices.Instance); 
       SetProviderFactory ("Npgsql", Npgsql.NpgsqlFactory.Instance); 
       SetDefaultConnectionFactory (new Npgsql.NpgsqlConnectionFactory()); 
      } 
     } 

     [DbConfigurationType(typeof(NpgsqlConfiguration))] 
     public class PlayerContext : DbContext 
     {  
      public PlayerContext(DbConnection connection): base(connection, true) 
      {     
      } 

      public DbSet<Player> Players { get; set; } 
      protected override void OnModelCreating(DbModelBuilder modelBuilder) 
      { 

       modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 
       //modelBuilder.Conventions.Add<CascadeDeleteAttributeConvention>(); 
       modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
       modelBuilder.HasDefaultSchema("public"); 
       base.OnModelCreating(modelBuilder); 
      }   
     } 

这里是我的app.config文件

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <configSections> 
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> 
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 
    </configSections> 
    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 
    </startup> 
    <entityFramework> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> 
     <parameters> 
     <parameter value="v12.0" /> 
     </parameters> 
    </defaultConnectionFactory> 
    <providers> 
     <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
     <provider invariantName="Npgsql" type="Npgsql.NpgsqlServices, EntityFramework6.Npgsql" /> 
    </providers>  
    </entityFramework> 
    <runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <dependentAssembly> 
     <assemblyIdentity name="Npgsql" publicKeyToken="5d8b90d52f46fda7" culture="neutral" /> 
     <bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" /> 
     </dependentAssembly> 
    </assemblyBinding> 
    </runtime> 
    <system.data> 
    <DbProviderFactories> 
     <add name="Npgsql Data Provider" 
      invariant="Npgsql" 
      description="Data Provider for PostgreSQL" 
      type="Npgsql.NpgsqlFactory, Npgsql" /> 
    </DbProviderFactories> 
    </system.data> 
    <connectionStrings> 
    <add name="PlayerContext" connectionString="Username=hjanadgkizjmgf;Password=password;Host=ec2-54-235-250-156.compute-1.amazonaws.com;Port=5432;Database=deek4ap6cf2a1;Pooling=true;Use SSL Stream=True;SSL Mode=Require;TrustServerCertificate=True;" providerName="Npgsql" /> 
    </connectionStrings> 
</configuration> 

当我通过直接在连接字符串中 - 这工作这么好提前检索记录的同一个,我得到这个奇怪的例外:

“关键字不被支持'用户名'” - 显然是指连接字符串传入的 。

using (var db = new PlayerContext(sqlBuilder.ToString())) 
       { // etc } 

而且奇怪的是,我在编译之前发出警告:

“警告不同版本的同一 依赖程序集的,可能无法得到解决之间1个发现冲突。当日志详细程度设置为 详细信息时,会在构建日志中列出这些参考 冲突。 pg-EF-test2“或许与Npgsql有关?

任何援助将不胜感激。

回答

6

看起来像当前版本中的“EntityFramework6.Npgsql”nuget包含错误定义的依赖关系。它列出了“Npgsql(> = 3.1.0)”作为依赖项,但它实际上需要版本3.1.2或更高版本中的Npgsql。

所以修复很简单 - 只需将Npgsql包更新到最新版本即可。 “更新包Npgsql”应该做的伎俩。

而对于带有字符串参数的上下文构造函数 - 您会看到一个奇怪的异常,因为该构造函数期望您从配置文件中传递连接字符串的名称。你应该使用这样的:

using (var db = new PlayerContext("PlayerContext")) 
{ } 
+0

谢谢,终于找到了这1天试图解决我的多供应商多上下文建立搜索〜之后,实际上这是我唯一的问题。 (从3.1.0升级到3.2.6的Npgsql) –