当我尝试使用以下代码通过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正确处理它。
答案 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)。