PostgreSQL和实体框架的超时问题

时间:2016-04-20 11:35:13

标签: 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:取消声明由于   声明超时“}

     

消息:57014:取消由于的声明   声明超时

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

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正确处理它。

1 个答案:

答案 0 :(得分:4)

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

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

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