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

本文关键字:连接 字符串 错误 Npgsql 框架 实体 | 更新日期: 2023-09-27 18:17:59

一个棘手的(令人沮丧的)问题——也许你们足够聪明来解决它:

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

System.Data.Entity.Core。ProviderIncompatibleException:错误从数据库获取提供程序信息时发生。这是否可以由实体框架使用不正确的连接引起字符串。检查内部异常的详细信息,并确保连接字符串正确。--->System.Data.Entity.Core.ProviderIncompatibleException:提供程序没有返回一个ProviderManifestToken字符串。--->system . io . fileloadeexception:无法加载文件或程序集Npgsql,版本=3.1.2.0,文化=中性,PublicKeyToken=5d8b90d52f46fda7' or它的一个依赖项。定位程序集的清单定义与程序集引用不匹配。(来自HRESULT的例外:0 x80131040)

下面是堆栈跟踪:

   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;

这是我的"你好世界",我用它来连接和读取我的数据库(从球员表)。它成功地将"莱昂内尔·梅西"打印到控制台上。太棒了!

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

当我直接传递一个连接字符串时-与之前检索记录的连接字符串相同,我得到了这个奇怪的异常:

"关键字不支持' username ' " -显然指的是连接字符串传入。

using (var db = new PlayerContext(sqlBuilder.ToString()))
                { // etc }
同样奇怪的是,我在编译前收到一个警告:

"警告1发现相同的不同版本之间存在冲突无法解析的从属程序集。这些参考当日志详细度设置为时,冲突将在构建日志中列出详细的。pg-EF-test2"也许这与Npgsql有关?

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

看起来像"EntityFramework6 "。Npgsql" nuget包在当前版本中定义的依赖项不正确。它列出了"Npgsql(>= 3.1.0)"作为依赖项,但它实际上需要Npgsql在3.1.2或更高版本。

所以修复很简单-只需将Npgsql包更新到最新版本。"Update-Package Npgsql"应该可以解决这个问题。

对于带有字符串参数的上下文构造函数,您会遇到一个奇怪的异常,因为该构造函数希望您从配置文件中传递连接字符串的名称。你应该这样使用它:
using (var db = new PlayerContext("PlayerContext"))
{ }