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) 默认连接工厂的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework 5.0 PostgreSQL (Npgsql) 默认连接工厂
Entity Framework 5.0系列之自动生成Code First代码
如何使用 Entity Framework Core 5.0 将复杂 SQL 查询的结果行映射到自定义 DTO?
Entity Framework Core 5.0 如何将多对多连接的 LINQ 转换为使用 ASP.NET 成员资格的交集表