c# - PostgreSQL 和 Entity Framework 的超时问题

标签 c# entity-framework linq postgresql npgsql

当我尝试使用以下代码通过 EntityFramework6.Npgsql 查询 PostgreSQL 数据库时:

using (MyDbContext context = new MyDbContext())
{
   var res = (from b in context.mytable select new { b.Name, b.Age }); 
   foreach (var row in res)
   {
      Console.WriteLine(row.Name + " - " + row.Age);
   }
}

在获取几行后出现超时异常并出现以下错误:

[Npgsql.NpgsqlException] : {"57014: canceling statement due to statement timeout"}

Message: 57014: canceling statement due to statement timeout

当我在将所有数据提取到列表中时执行相同的操作时,代码工作正常:

using (MyDbContext context = new MyDbContext())
{
   var res = (from b in context.mytable select new { b.Name, b.Age }).ToList(); 
   foreach (var row in res)
   {
      Console.WriteLine(row.Name + " - " + row.Age);
   }
}

我怀疑它与 PostgreSQL 管理其连接池的方式有关,但我不知道如何通过 Entity Framework 正确处理它。

最佳答案

这可能与 Npgsql 管理超时的方式有关。在当前版本中,Npgsql 设置了 PostgreSQL statement_timeout 变量,这会导致 PostgreSQL 在一段时间后生成超时错误。此方法的问题在于 statement_timeout 对此不可靠:它包括网络时间、客户端处理时间等。因此在客户端花费太多时间可能会使服务器生成错误。

在您的示例中,调用 ToList() 意味着您立即下载所有结果,而不是一点一点地遍历它们。我承认奇怪的是,如此短的客户端处理(即 Console.WriteLine)可能会引入足以触发后端超时的延迟(命令超时设置为多少?)。

请注意,由于 statement_timeout 的不可靠特性,Npgsql 的下一个主要版本将完全删除后端超时 - 参见 https://github.com/npgsql/npgsql/issues/689 .现在,您可以通过将 Backend Timeouts 连接字符串参数设置为 false 来手动禁用后端超时(参见 http://www.npgsql.org/doc/3.0/connection-string-parameters.html )。

关于c# - PostgreSQL 和 Entity Framework 的超时问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36742572/

相关文章:

c# - 在自己的控制中传递验证错误

c# - 从 byte[] 下载文件 C# MVC

c# - 从 Entity Framework 中删除具有多对多关系的对象?

c# - {"error":"Explicit construction of entity type ' ## #' in query is not allowed."}

c# - Entity Framework 共享查询

c# - 如何从任何对象属性为 null 或空的列表中删除所有?

c# - 使用 LINQ 对分层数据进行分组

c# - 如何制作采用泛型类型的泛型方法

c# - 从引发的异常中恢复或返回

c# - Linq to SQL 是用户日期范围与数据库日期范围相交