Entity Framework 5.0 PostgreSQL (Npgsql) 默认连接工厂
Posted
技术标签:
【中文标题】Entity Framework 5.0 PostgreSQL (Npgsql) 默认连接工厂【英文标题】:Entity Framework 5.0 PostgreSQL (Npgsql) default connection factory 【发布时间】:2013-02-04 16:03:33 【问题描述】:我正在尝试让 EF 5.0 代码首先与 PostgreSQL(Npgsql 提供程序)一起使用。我通过 NuGet 安装了 Npgsql 2.0.12.1(尽管引用的程序集是 2.0.12.0)。 我在 app.config 中声明了 Npgsql(默认连接工厂和提供程序工厂):
<entityFramework>
<defaultConnectionFactory type="Npgsql.NpgsqlFactory, Npgsql, Version=2.0.12.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7" />
</entityFramework>
<system.data>
<DbProviderFactories>
<add name="Npgsql Data Provider"
invariant="Npgsql"
description="Data Provider for PostgreSQL"
support="FF"
type="Npgsql.NpgsqlFactory, Npgsql, Version=2.0.12.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7"/>
</DbProviderFactories>
</system.data>
我已成功运行以下测试:
[Test]
public void DatabaseConnection_DatabaseFactoryTest()
var factory = DbProviderFactories.GetFactory("Npgsql");
var conn = factory.CreateConnection();
conn.ConnectionString = _connectionString;
var npg = (NpgsqlConnection)conn;
var result = TestConnectionHelper(npg); // scalar select version(), nothing particular
Assert.AreEqual(result, "PostgreSQL 9.2.2, compiled by Visual C++ build 1600, 64-bit");
这意味着至少数据库实例正在运行并且提供程序已成功配置。 现在我想要的是使用从 DbContext 继承的自定义数据库上下文,它将绑定到同一个提供程序并通过连接字符串初始化:
public class InventoryContext : DbContext
public InventoryContext(string nameOrConnectionString) : base(nameOrConnectionString)
// mappings and properties, cut for conciseness
以下测试失败:
[Test]
public void DatabaseConnection_DatabaseContextTest()
using (var ctx = new InventoryContext(_connectionString))
//var db = ctx.Database;
ctx.InventoryObjects.Add(_inventoryObject); // exception here
ctx.SaveChanges();
它说
Failed to set Database.DefaultConnectionFactory to an instance of the 'Npgsql.NpgsqlFactory, Npgsql, Version=2.0.12.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7' type as specified in the application configuration. See inner exception for details.
内部异常是 InvalidOperationException :
"Constructor for type \"Npgsql.NpgsqlFactory\" is not found."
我猜连接字符串有问题(它不包含 Npgsql 提供程序):
"Server=127.0.0.1;Port=5432;User Id=postgres;Password=p4ssw0rd;Database=InventoryDatabase;";
以编程方式解决此问题的最优雅的方法是什么?刚刚尝试将 app.config 中的 connectionString 传递给上下文的构造函数,它可以工作。edit 将测试项目上传到 Dropbox - VS2012 solution, 10 mb
【问题讨论】:
嗨! nuget 包中的最后一个 .1 是因为我无法更新 2.0.12 包。包中缺少一个文件,我不得不更新它。但请放心,Npgsql 二进制文件与 2.0.12 版本相同。 :) 你介意把这个示例项目发给我,让我看看吗?我认为这可能是 Npgsql 中的一个错误,它可能缺少 EF 所期望的构造函数。我的电子邮件是 npgsql dor org 的 francisco。提前致谢。 版本不是问题,尽管我花了一些时间找出为什么在运行时找不到程序集。关键在于连接字符串配置,尤其是在我的生产环境中,我无法使用/修改 .config 文件(在 IIS 限制中发布的 WPF XBAP 应用程序)。将在几个小时内向您发送示例项目。 发送示例项目,如果其他人想看,请添加 Dropbox 下载链接。 【参考方案1】:深入挖掘问题,发现这是由于 Npgsql 引用 EntityFramework 4.4.0 程序集这一事实引起的。解决如下:
-
为测试项目添加了 EF Nuget 包(针对 FW 4.5 构建);
在Npgsql2010项目中手动添加对EntityFramework.dll版本5的引用(Nuget默认添加4.4.0);
将 Npgsql app.config 中的程序集绑定更改为 "EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
通过将构造函数公开,修复了上述“找不到类型“Npgsql.NpgsqlFactory”的构造函数错误;
通过在 NpgsqlFactory 上实现 IDbConnectionFactory 接口修复了以下错误“无法将 NpgsqlFactory 转换为 IDbConnectionFactory”:
使用 System.Data.Entity.Infrastructure; ... 公共密封类 NpgsqlFactory:DbProviderFactory、IServiceProvider、IDbConnectionFactory ... 公共 DbConnection CreateConnection(字符串名称或连接字符串) 返回新的 NpgsqlConnection(nameOrConnectionString); d
现在我遇到与 EF 相关的“错误:3F000:架构“dbo”不存在”。我已经映射到 DbContext 的 OnModelCreating 中的 PostgreSQL 标准公共模式:modelBuilder.Entity().ToTable("TableName", "public") 虽然。期待解决这个问题。
【讨论】:
太棒了!我将立即添加报告的缺失部分:构造函数可见性和接口实现。感谢您检查。 我觉得我跳得太快了。在查看 msdn 文档时,我注意到 SqlClientFactory 是一回事,而 SqlConnectionFactory 是另一回事。 NpgsqlFactory 相当于 SqlClientFactory。为了解决这个问题,我们需要创建另一个名为 NpgsqlConnectionFactory 的类,它将绑定到实体框架支持。对此感到抱歉。我会检查我们将如何做到这一点。 我已经放弃使用 EntityFramework 与 PostgreSQL 和 Npgsql 这些问题已得到修复。在它变得更稳定之前,我无法投入生产。 大家好!我刚刚提交了一项贡献,增加了对 EF6 的初始支持。您可以在我的帖子中看到更多信息:fxjr.blogspot.com/2013/06/… 请试一试,让我知道它是否适合您。以上是关于Entity Framework 5.0 PostgreSQL (Npgsql) 默认连接工厂的主要内容,如果未能解决你的问题,请参考以下文章