实体框架6 - Npgsql - 连接字符串错误

时间:2016-11-15 01:58:41

标签: c# heroku entity-framework-6 connection-string npgsql

一个棘手的(令人沮丧的问题) - 也许你们大家可能很聪明地解决它:

问题

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

  

System.Data.Entity.Core.ProviderIncompatibleException:错误   从数据库获取提供程序信息时发生。这个   可能是由实体框架使用不正确的连接引起的   串。检查内部异常以获取详细信息并确保   连接字符串是正确的。 --->   System.Data.Entity.Core.ProviderIncompatibleException:提供程序   没有返回ProviderManifestToken字符串。 --->   System.IO.FileLoadException:无法加载文件或程序集' Npgsql,   Version = 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有关?

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:9)

看起来像&#34; EntityFramework6.Npgsql&#34;当前版本中的nuget包具有错误定义的依赖项。它列出了&#34; Npgsql(&gt; = 3.1.0)&#34;作为依赖项,但它实际上需要3.1.2或更高版本中的Npgsql。

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

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

using (var db = new PlayerContext("PlayerContext"))
{ }
相关问题