Мы недавно обновили наше решение с Visual Studio 2010 до VS 2017 и .NET Framework 4.0 до 4.6.1.
В базе данных, работающей на Postgres 9.4, нет изменений.
Это также включало в себя обновление DLL Npgsql с версии 2 до версии 3.
У нас есть фрагмент кода, как показано ниже:
using (MemoryStream memoryStream = new MemoryStream())
{
dataTable.WriteXml(memoryStream, XmlWriteMode.IgnoreSchema);
.
.
.
У нас есть хранимая процедура PostgreSQLкоторая возвращает столбцы типов данных массива (string [], bool [], int [] и т. д.).
В .NET 4.0, версия NpgSql 2, приведенная выше, работала нормально, без проблем.Но с новой настройкой мы получаем ошибку сериализации.
Type 'System.String[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' does not implement IXmlSerializable interface therefore can not proceed with serialization. at System.Data.XmlDataTreeWriter.XmlDataRowWriter(DataRow row, String encodedTableName)
at System.Data.XmlDataTreeWriter.Save(XmlWriter xw, Boolean writeSchema)
at System.Data.DataTable.WriteXml(XmlWriter writer, XmlWriteMode mode, Boolean writeHierarchy)
at System.Data.DataTable.WriteXml(Stream stream, XmlWriteMode mode, Boolean writeHierarchy)
Главное, что я мог заметить в отладчике VS, это то, что DataType этих столбцов массива отображается как «System.Array» из VS 2017, нораньше (в 2010 году) он показывал массив определенного типа, например "System.String []".
Кто-нибудь знает, что здесь происходит?Любая помощь / предложение высоко ценится.
Вот простой код, который можно использовать для репликации проблемы.
using System.Configuration;
using Npgsql;
using System.Data;
using System.IO;
namespace NpgSqlArrayTest
{
public class Program
{
public static void Main(string[] args)
{
string connectionString = ConfigurationManager.ConnectionStrings["TestConnection"].ConnectionString;
NpgsqlConnection npgsqlConnection = new NpgsqlConnection(connectionString);
DataTable resultTable = new DataTable();
NpgsqlDataAdapter npgsqlDataAdapter = new NpgsqlDataAdapter("select * from \"FunctionReturnsArray\"();", npgsqlConnection);
npgsqlConnection.Open();
npgsqlDataAdapter.Fill(resultTable);
resultTable.TableName = "FunctionReturnsArray";
npgsqlConnection.Close();
using (MemoryStream memoryStream = new MemoryStream())
{
resultTable.WriteXml(memoryStream, XmlWriteMode.IgnoreSchema);
}
}
}
}
Это хранимая процедура.
CREATE OR REPLACE FUNCTION "FunctionReturnsArray"()
RETURNS integer[] AS
$BODY$
declare
v_Count integer;
v_Array integer[];
begin
v_Count = 0;
while v_Count < 10 loop
v_Array = array_append(v_Array, v_Count);
v_Count = v_Count + 1;
end loop;
return v_Array;
end;
$BODY$
LANGUAGE plpgsql STABLE
COST 100;