:: Не фоксом единым
C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Есть функция, которая возвращает 1 в случае удачного выполнения, 0 - в случае, если при выполнении были ошибки.

CREATE OR REPLACE FUNCTION public."MyFunc"()
RETURNS integer
LANGUAGE plpgsql
AS $function$
DECLARE
begin
[ тут куча кода ]
RETURN 0;
END
$function$;

Функция работает одну минуту (если точнее - 56 секунд). Вызов то же работает:

DbContext.Database.CommandTimeout = 3000;
var returnCode = DbContext.Database.SqlQuery<int>("SELECT * FROM \"MyFunc\"()").ToList();
if (returnCode[0] == 0) // 0 - есть ошибки
{
throw new Exception("Ошибка");
}

Хочу изменить вызов:

DbContext.Database.CommandTimeout= 300;
NpgsqlConnection conn = (NpgsqlConnection)DbContext.Database.Connection;
//conn.CommandTimeout = 300;
conn.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand("\"MyFunc\"", conn))
{
cmd.CommandTimeout = 300;
cmd.CommandType = CommandType.StoredProcedure;
NpgsqlParameter returnCode = new NpgsqlParameter("@ReturnCode", NpgsqlDbType.Integer)
{
Direction = ParameterDirection.Output
};
cmd.Parameters.Add(returnCode);
cmd.ExecuteNonQuery();
if ((int)returnCode.Value == 0) // 0 - есть ошибки
{
throw new Exception("Ошибка");
}
}

После 20-ти секунд выполнения падает с ошибкой 57014:

Цитата:
выполнение оператора отменено из-за тайм-аута

На сколько вижу, 20 секунд указано:

[attachment 31955 s1.png]

Однако, это поле только для чтения - поменять его не возможно:

[attachment 31956 s2.png]

Вопрос - как установить conn.CommandTimeout? Или, возможно, проблема не в conn.CommandTimeout - надо установить какой то другой таймаут?
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Через строку соединения управляется www.npgsql.org
Для формирования строки соединения можно использовать вспомогательный класс NpgsqlConnectionStringBuilder (там есть вполне readwrite свойство CommandTimeout). Очевидно, провайдер не позволяет "на лету" менять параметры соединения, да и не нужно этого по большому счёту


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
При старте приложения создаётся System.Data.Entity.DbContext, из Web.config извлекается нужная ConnectionString. О ней речь? думаю, не о ней, а о ConnectionString объекта conn типа NpgsqlConnection:

NpgsqlConnection conn = (NpgsqlConnection)DbContext.Database.Connection;
conn.Open();

Так?

Но, в данном случае, conn получается из DbContext.Database.Connection. Т.е. надо conn создавать как то иначе? Или, создавать так же, но менять ConnectionString?

Igor Korolyov
да и не нужно этого по большому счёту

Как же тогда сделать, что бы cmd.ExecuteNonQuery(); не вываливалась по таймауту через 20 секунд?
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Вот такой код тоже работает без проблем:

using (var command = DbContext.Database.Connection.CreateCommand())
{
command.CommandTimeout = 300;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "\"MyFunc\"";
command.Connection.Open();
int returnCode = (int)command.ExecuteScalar();
if (returnCode == 0) // 0 - есть ошибки
{
throw new Exception("Ошибка");
}
}

Тут новый connection не создаётся. Хотя... команда Open требуется - вероятнее всего, новый connection создаётся как то неявно. А при явном создании какие то ошибки.



Исправлено 1 раз(а). Последнее : S-type, 22.09.19 11:07
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
S-type
Но, в данном случае, conn получается из DbContext.Database.Connection.
А откуда по твоему берётся строка подключения для DbContext.Database.Connection?


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
S-type
Но, в данном случае, conn получается из DbContext.Database.Connection.
А откуда по твоему берётся строка подключения для DbContext.Database.Connection?

Чуть выше писал:

S-type
При старте приложения создаётся System.Data.Entity.DbContext, из Web.config извлекается нужная ConnectionString.

Эту строку я могу поменять, но - не нужно, т.к. таймаут нужно установить не для всех запросов, которые выполняет программа, а только для одного.



Исправлено 2 раз(а). Последнее : S-type, 22.09.19 21:26
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Как раз таки, проблема в том и заключается - что не могу установить таймаут для отдельной команды (вызова хранимой процедуры):

DbContext.Database.CommandTimeout= 300;
NpgsqlConnection conn = (NpgsqlConnection)DbContext.Database.Connection;
//conn.CommandTimeout = 300; - так нельзя
conn.Open();
using (NpgsqlCommand cmd = new NpgsqlCommand("\"MyFunc\"", conn))
{
cmd.CommandTimeout = 300; - программа просто игнорирует!
cmd.CommandType = CommandType.StoredProcedure;
NpgsqlParameter returnCode = new NpgsqlParameter("@ReturnCode", NpgsqlDbType.Integer)
{
Direction = ParameterDirection.Output
};
cmd.Parameters.Add(returnCode);
cmd.ExecuteNonQuery();
if ((int)returnCode.Value == 0)
{
throw new Exception("Ошибка");
}
}



Исправлено 1 раз(а). Последнее : S-type, 22.09.19 21:30
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Почитай внимательнее документацию, и issues связанные с этим самым CommandTimeout в официальном репозитории github.com
Возможно тебе надо помимо таймаута для SqlCommand ещё и серверный таймаут настраивать - постгрес умеет убивать сильно долгоиграющие запросы/вызовы со стороны сервера - возможно именно в серверном таймауте дело, а не в клиентском...

Ты же не приводишь ни версии используемых компонент, ни законченого примера демонстрирующего ошибку, как тогда рассчитываешь что кто-то сможет реально помочь


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Спасибо - почитаю.

Проблема не горящая... В реальной программе работает самый первый из приведённых фрагментов. А для себя пытаюсь разобраться и понять - как всё это работает.
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
Ты же не приводишь ни версии используемых компонент, ни законченого примера демонстрирующего ошибку

Вресии?

VisualStudio 2019 Comunity.
NeGet:
EntityFramework 6.2.0.
Npgsql.EntityFramework 2.2.7
PostgreSql 10.10



Исправлено 2 раз(а). Последнее : S-type, 22.09.19 23:56
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
S-type
VisualStudio 2019 Comunity
Важнее чем IDE тулза то, под какую платформу пишешь проект - net4xx, что-то ещё более древнее (надеюсь 2019 студия не поддерживает уже фреймворки линейки 2.0 ) или, вдруг какой-то из core

S-type
EntityFramework 6.2.0.
Ну значит под какой-то из Full .Net Framework. 2-годичной давности версия. Что мешает обновиться то? Крепко в продакшне проект и нет планов по выпуску хотя бы minor новой версии, только багфиксы?

S-type
Npgsql.EntityFramework 2.2.7
ох-хо-хо, last updated 9/18/2015 - печально это...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Проект под 4.7.1, в заключительной фазе - уже пишется следующая версия, а в данной обновление NuGet пакетов заморожено, но возможно - если покажу, что в новой версии решены какие то проблемы или есть какие то плюсы. Обновляться до 4.8 в этой версии софта уже не будем, а на счёт Npgsql.EntityFramework 2.2.7 - а есть ли альтернатива?
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Не в курсе. По идее актуальная версия под EF6 это EntityFramework6.Npgsql 3.2.1.1
Но как там дело обстоит с таймаутами - понятия не имею.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
По идее актуальная версия под EF6 это EntityFramework6.Npgsql 3.2.1.1
Спасибо за наводку, попробую.
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Начал пробовать перевести программу с Npgsql.EntityFramework 2.2.7 на EntityFramework6.Npgsql 3.2.1.1. Столкнулся с тем, что уже работающий код перестал работать.

Есть хранимая процедура, допускающая null в одном из параметров:

CREATE OR REPLACE FUNCTION public."GetUsers"(user_id integer, description text DEFAULT NULL::text)
RETURNS TABLE("Id" integer, "Name" varchar, "Surname" varchar, description text)
LANGUAGE sql
AS $function$
select "Id","Name","Surname", description
from "Users"
where "Id"=user_id;
$function$;

Вызываю с Npgsql.EntityFramework 2.2.7 - всё работает. Вызываю с EntityFramework6.Npgsql 3.2.1.1, вижу:

[attachment 31998 s1.png]

Вот проект [attachment 31999 TestEntity1.zip]
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Конечно, можно значение каждого параметра проверить на null, и если равен - передавать DBNull.Value. Но, код станет весьма не красивым.
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Хотя, в принципе, можно какую то обёртку написать.
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
github.com
Ну и само обоснование:
docs.microsoft.com
Цитата:
When you send a null parameter value to the server, you must specify DBNull, not null. The null value in the system is an empty object that has no value. DBNull is used to represent null values.


------------------
WBR, Igor




Исправлено 1 раз(а). Последнее : Igor Korolyov, 02.10.19 00:13
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
[attachment 32013 s1.png]

Как в анекдоте - это не баг, это фича...



Исправлено 2 раз(а). Последнее : S-type, 02.10.19 08:40
Ratings: 0 negative/0 positive
Re: C# - вернуть значение из функции Postgresql
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Ещё один фрагмент перестал работать - чтение данных из refcursor-а

[attachment 32014 s2.png]

Вот проект [attachment 32015 Pg_1.zip]

CREATE OR REPLACE FUNCTION public.show_cities()
RETURNS SETOF refcursor
LANGUAGE plpgsql
AS $function$
DECLARE
ref1 refcursor='mycursor1';
ref2 refcursor='mycursor2';
BEGIN
OPEN ref1 FOR SELECT 1 "Id", 'описание' "Description";
RETURN next ref1;
OPEN ref2 FOR SELECT 2 "Id", 'описание 2' "Description";
return next ref2;
END;
$function$
;

Тут точно не "уважением стандартов"
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 5 (Гостей: 5)

© 2000-2024 Fox Club 
Яндекс.Метрика