使用Npgsql 3.1.5我尝试使用NpgsqlCommand.ExecuteReader()
从表中加载数据。一些列是自定义Postgres类型。我想把它们作为文本阅读,就像Npgsql 2.2一样。默认情况下,Npgsql 3.1会为这些引发错误:
System.NotSupportedException : The field 'my_custom_type_field' has a type currently unknown to Npgsql (OID 50064). You can retrieve it as a string by marking it as unknown, please see the FAQ.
FAQ建议设置AllResultTypesAreUnknown
或指定哪些列未知,但这些都不是一个好的解决方案。 AllResultTypesAreUnknown
将所有列读为字符串,这对我来说毫无用处。逐个指定各个列名称比升级代码以正确使用自定义类型需要更多的工作,因为有许多表和许多查询。我不想将所有类型作为字符串读取,我只想将 unknown 类型作为字符串读取。换句话说,当Npgsql抛出上述异常时,读为字符串。有没有办法解决这个问题?
答案 0 :(得分:1)
TL; DR Npgsql无法透明地只读取未知列作为文本,您必须使用AllResultTypesAreUnknown
,UnknownResultTypeList
或更改SQL查询以将未知列转换为文本。
以下是为什么这些是你唯一选择的(太多)长篇答案。
PostgreSQL在读取和写入值时支持两种编码:二进制和文本。 Npgsql 2.2曾经使用文本编码,这意味着当您读取或写入值时,Npgsql必须为您的值解析或生成文本表示。文本表示意味着人类而不是程序化的消费,除了非常低效之外,这导致了许多错误,因为解析文本表示很难确定100%。另请注意,Npgsql 2.2确实在某些案例中使用二进制表示(即准备好的语句),使驱动程序更加复杂和不可预测。
Npgsql 3.0取消了所有这些,并转而使用纯二进制方法。这简化了许多事情并改进了性能,但是在未知字段方面产生了一个问题:只要Npgsql知道如何读/写一个类型的二进制表示都是好的;但是,虽然未知类型的文本表示对用户有意义,但二进制表示却没有。
问题是结果的编码(文本或二进制)是在发送查询时预先确定的。如果您在未指定AllResultTypesAreUnknown
/ UnknownResultTypeList
的情况下发送查询,Npgsql将返回一个它不知道的二进制表示。在这一点上,做任何事都为时已晚,除了重新发送查询 - 这不是一个选项。所以如果你想要一个文本表示,你必须事先让Npgsql知道。