实体框架6 - Npgsql - 连接字符串错误 [英] Entity Framework 6 - Npgsql - connection string error

查看:747
本文介绍了实体框架6 - Npgsql - 连接字符串错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



问题



我希望能够使用实体框架读/写我的数据库。我有一个简单的应用程序轨道运行在Heroku(直接脚手架)。我想连接到这个数据库并操纵记录。好消息是,我可以使用npgsql成功连接到该数据库。坏消息是我不能用实体框架来实现。这是我收到的错误:


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)


这是堆栈跟踪:



$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ---内部异常堆栈跟踪结束---
在System.Data.Entity.Core.Common.DbProviderServices.GetProviderManifestToken(DbConnection连接)
在System.Data.Entity.Utilities.DbProviderServicesExtensions.GetProviderManifestTokenChecked (DbProviderServices providerServices,DbConnection连接)
---内部异常堆栈跟踪结束---
在System.Data.Entity.Utilities.DbProviderServicesExtensions.GetProviderManifestTokenChecked(DbProviderServices providerServices,DbConnection连接)
在System.Data.Entity.Infrastructure.DefaultManifestTokenResolver。  c__DisplayClass1。&ResolveManifestToken> b__ 0(Tuple`3 k)
在System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key,Func`2 valueFactory)
在System.Data.Entity.Infrastructure.DefaultManifestTokenResolver.ResolveManifestToken(DbConnection连接)
在System.Data.Entity.Utilities.DbConnectionExtensions.GetProviderInfo(DbConnection连接,DbProviderManifest& providerManifest)
在System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
在System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
在System.Data.Entity .Internal.RetryLazy`2.GetValue(TInput input)
在System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
在System.Data.Entity.Internal.InternalContext.Initialize()
在System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
在System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
在System.Data.Entity .Internal.Linq.InternalSet`1.get_InternalContext()
在System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider()
在System.Linq.Queryable.Select [TSource,TResult](IQueryable`1 source,Expression`1 selector)
at ge_EntityFrameworkTest.Program。< Test> d__4.MoveNext()in c:\Users\Koshy\Documen ts\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 connectAndReadingDatabase 
using(var conn = new NpgsqlConnection(sqlBuilder.ToString()))
{
conn.Open();
使用(var cmd = new NpgsqlCommand())
{
cmd.Connection = conn;

//检索所有行
cmd.CommandText =SELECT * FROM players;
使用(var reader = cmd.ExecuteReader())
{
while(reader.Read())
{
Console.WriteLine(reader.GetString(1 ));
}
}
}
}
#endregion

问题是当我尝试使用实体框架。它以痛苦的错误大量失败。我正在使用完全相同的连接字符串,并且不能为我的生活工作在哪里我错了。也许你可以轻松找到问题?

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


//这是关于我的hello world实体框架示例的代码:

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

class Np​​gsqlConfiguration: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>玩家{get;组;
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.0encoding =utf-8?> 
< configuration>
< configSections>
<! - 有关实体框架配置的更多信息,请访问http://go.microsoft.com/fwlink/?LinkID=237468 - >
< section name =entityFrameworktype =System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection,EntityFramework,Version = 6.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089requirePermission =false/> ;
< / configSections>
< startup>
< supportedRuntime version =v4.0sku =。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.SqlClienttype =System.Data.Entity.SqlServer.SqlProviderServices,EntityFramework.SqlServer/>
< provider invariantName =Npgsqltype =Npgsql.NpgsqlServices,EntityFramework6.Npgsql/>
< / providers>
< / entityFramework>
<运行时>
< assemblyBinding xmlns =urn:schemas-microsoft-com:asm.v1>
< dependentAssembly>
< assemblyIdentity name =NpgsqlpublicKeyToken =5d8b90d52f46fda7culture =neutral/>
< bindingRedirect oldVersion =0.0.0.0-3.1.0.0newVersion =3.1.0.0/>
< / dependentAssembly>
< / assemblyBinding>
< / runtime>
< system.data>
< DbProviderFactories>
< add name =Npgsql数据提供者
invariant =Npgsql
description =PostgreSQL的数据提供者
type =Npgsql.NpgsqlFactory,Npgsql/> ;
< / DbProviderFactories>
< /system.data>
< connectionStrings>
< add name =PlayerContextconnectionString =Username = hjanadgkizjmgf; Password = password; Host = ec2-54-235-250-156.compute-1.amazonaws.com; Port = 5432; Database = deek4ap6cf2a1 ; Pooling = true;使用SSL Stream = True; SSL Mode = Require; TrustServerCertificate = True; providerName =Npgsql/>
< / connectionStrings>
< / configuration>

当我直接传递一个连接字符串 - 同样的工作,我得到这个好奇的例外:


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




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

另外好奇的是,我在编译之前收到一条警告:


警告1发现无法解析的相同
依赖程序集的不同版本之间发生冲突。当log verbosity设置为
时,构建日志中列出了这些引用
冲突。 pg-EF-test2也许这与Npgsql有关?


任何帮助都将不胜感激。

解决方案

看起来像当前版本中的EntityFramework6.Npgsqlnuget包具有不正确的依赖关系。它列出了Npgsql(> = 3.1.0)作为依赖关系,但它实际上需要版本3.1.2或更高版本中的Npgsql。



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



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

  using(var db = new PlayerContext(PlayerContext))
{}


A tricky (and frustrating problem) - perhaps you folks may be clever enough to solve it:

Problem

I want to be able to read/write to my database using Entity Frameworks. I have got a simple app rails running on Heroku (straightforward scaffold). I want to connect to this database and manipulate records. The good news is that I can successfully connect to that database using npgsql. The bad news is that I cannot do it with Entity Frameworks. This is the error I’m receiving:

System.Data.Entity.Core.ProviderIncompatibleException: An error occurred while getting provider information from the database. This can be caused by Entity Framework using an incorrect connection string. Check the inner exceptions for details and ensure that the connection string is correct. ---> System.Data.Entity.Core.ProviderIncompatibleException: The provider did not return a ProviderManifestToken string. ---> System.IO.FileLoadException: Could not load file or assembly 'Npgsql, Version=3.1.2.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Here is the stack trace:

   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

Here is my connection string:

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;

Here is my "Hello world" that I am using to connect and read from my database (from the players table). It is successfully printing: "Lionel Messi" on to the console. Great!

            #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

The problem is when I try to use Entity Frameworks. It fails massively with a painful error. I am using exactly the same connection string, and cannot for the life of me work out where I’m going wrong. Perhaps you may be able to easily spot the problem?

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

And here is my app.config file

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

When I pass in a connection string directly - the same one which worked so well to retrieve records earlier, I get this curious exception:

"Keyword not supported ‘username’" – obviously referring to the connection string passed in.

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

Also curiously, I receive a warning before compiling:

"Warning 1 Found conflicts between different versions of the same dependent assembly that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed. pg-EF-test2" perhaps it’s something to do with Npgsql?

Any assistance would be much appreciated.

解决方案

Looks like the "EntityFramework6.Npgsql" nuget package in the current version has incorrectly defined dependencies. It lists "Npgsql (>= 3.1.0)" as a dependency but it actually requires Npgsql in version 3.1.2 or higher.

So the fix is simple - just update the Npgsql package to the latest version. "Update-Package Npgsql" should do the trick.

And as for the context constructor with a string parameter - you got a weird exception because that constructor expects you to pass the name of the connection string from your config file. You should use it like this:

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

这篇关于实体框架6 - Npgsql - 连接字符串错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆