BKS*_*eon 1 c# connection-string heroku npgsql entity-framework-6
一个棘手的(令人沮丧的问题) - 也许你们大家可能很聪明地解决它:
问题
我希望能够使用Entity Frameworks读取/写入我的数据库.我有一个在Heroku(简单的脚手架)上运行的简单app rails.我想连接到这个数据库并操纵记录.好消息是我可以使用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)
这是堆栈跟踪:
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
Run Code Online (Sandbox Code Playgroud)
这是我的连接字符串:
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;
Run Code Online (Sandbox Code Playgroud)
这是我用来连接和读取数据库(来自播放器表)的"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
Run Code Online (Sandbox Code Playgroud)
问题是当我尝试使用实体框架时.它大大地失败了,带来了一个痛苦的错误.我正在使用完全相同的连接字符串,并且不能为我的生活找出我出错的地方.也许你可以轻松发现问题?
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的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>
Run Code Online (Sandbox Code Playgroud)
当我直接传入一个连接字符串 - 同一个工作得很好以便先检索记录时,我得到了一个奇怪的例外:
"关键字不支持'用户名'" - 显然是指传入的连接字符串.
using (var db = new PlayerContext(sqlBuilder.ToString()))
{ // etc }
Run Code Online (Sandbox Code Playgroud)
还奇怪的是,我在编译前收到警告:
"警告1发现无法解析的相同从属程序集的不同版本之间存在冲突.当日志详细程度设置为详细时,这些引用冲突将在构建日志中列出.pg-EF-test2"也许这与Npgsql有关?
任何援助将不胜感激.
看起来当前版本中的"EntityFramework6.Npgsql"nuget包具有错误定义的依赖项.它将"Npgsql(> = 3.1.0)"列为依赖项,但它实际上需要3.1.2或更高版本中的Npgsql.
因此修复很简单 - 只需将Npgsql包更新到最新版本即可."Update-Package Npgsql"应该可以解决问题.
至于带有字符串参数的上下文构造函数 - 您有一个奇怪的异常,因为该构造函数希望您从配置文件中传递连接字符串的名称.你应该像这样使用它:
using (var db = new PlayerContext("PlayerContext"))
{ }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3084 次 |
| 最近记录: |