2016-07-04 17 views
0

使用Npgsql 3.1.5我嘗試使用NpgsqlCommand.ExecuteReader()從表中加載數據。一些列是自定義Postgres類型。我想將它們作爲文本讀取,就像Npgsql 2.2用來做的那樣。默認情況下3.1 Npgsql的引發錯誤的那些:如何在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將所有列讀取爲字符串,這對我來說是無用的。因爲有許多表和許多查詢,所以逐個指定單獨的列名將花費比升級代碼以正確使用自定義類型更多的工作。我不想讀取所有的類型作爲字符串,我只想讀取未知的類型作爲字符串。換句話說,當Npgsql否則會拋出上述異常時,將其讀作字符串。有沒有辦法獲得這種行爲?

回答

1

TL; DR Npgsql無法透​​明地只讀未知列作爲文本,您必須使用AllResultTypesAreUnknown,UnknownResultTypeList或更改您的SQL查詢以將未知列轉換爲文本。

這是關於爲什麼這些是你唯一的選擇的(太多)長答案。

PostgreSQL在讀取和寫入值時支持兩種編碼:二進制和文本。 Npgsql 2.2用於使用文本編碼,這意味着當您讀取或寫入值時,Npgsql必須爲您的值解析或生成文本表示。文本表示的目的是爲了人類而不是程序化的消費,除了相當低效,這導致了很多錯誤,因爲解析文本表示很難100%確定。還要注意的是,Npgsql 2.2在的一些的情況下(即準備好的語句)的確使用二進制表示,使得驅動程序更加複雜和不可預測。

Npgsql 3.0消除了所有這些,並切換到純二進制方法。這簡化了很多事情並提高了性能,但是對未知字段產生了一個問題:只要Npgsql知道如何讀取/寫入類型的二進制表示,一切都很好;但是未知類型的文本表示對用戶來說可能是有意義的,但二進制表示不會。

問題是,發送查詢時預先確定結果的編碼(文本或二進制)。如果您發送的查詢沒有指定AllResultTypesAreUnknown/UnknownResultTypeList,Npgsql將返回一個二進制表示,它對此一無所知。此時,要做任何事情都爲時已晚,除非重新發送查詢 - 這不是一種選擇。所以如果你想要一個文本表示,你必須讓Npgsql提前知道。

+0

我明白了,謝謝你的詳細解釋。作爲解決方法,我可以以某種方式使用MapCompositeGlobally來將我的複合類型映射爲字符串嗎? – EM0

+0

沒有。 MapCompositeGlobally只是告訴Npgsql將給定PostgreSQL組合類型的* binary *表示序列化/反序列化爲給定的CLR類型。再次,Npgsql沒有辦法事先知道你的查詢將返回哪些列類型:當你發送'SELECT * FROM x'時,沒有人知道哪些列將被返回。 –

+0

您必須正確移植您的應用程序,最好是創建實際的CLR類型並將它們映射到PostgreSQL組合,或使用AllResultTypesAreUnknown/UnknownResultTypeList(或在您的查詢中添加強制轉換)。 –

相關問題