实体框架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有关?
看起来像"EntityFramework6 "。Npgsql" nuget包在当前版本中定义的依赖项不正确。它列出了"Npgsql(>= 3.1.0)"作为依赖项,但它实际上需要Npgsql在3.1.2或更高版本。
所以修复很简单-只需将Npgsql包更新到最新版本。"Update-Package Npgsql"应该可以解决这个问题。
对于带有字符串参数的上下文构造函数,您会遇到一个奇怪的异常,因为该构造函数希望您从配置文件中传递连接字符串的名称。你应该这样使用它:using (var db = new PlayerContext("PlayerContext"))
{ }