Разница между использованием `NpgsqlParameter <T>` и `AddWithValue` с` NpgsqlDbType` - PullRequest
2 голосов
/ 28 января 2020

Документация Npg sql гласит, что использование NpgsqlParameter<T> лучше, поскольку оно строго типизировано и не напрягает сборщик мусора из-за бесполезного выделения кучи, вызванного типами значений бокса.

У меня есть две нижеприведенные команды, которые объявляют тип данных для использования для заданного параметра c:

Не используется NpgsqlParameter<T>:

command.Parameters.AddWithValue("id", NpgsqlTypes.NpgsqlDbType.Integer, 123);

Использование NpgsqlParameter<T>:

cmd.Parameters.Add(new NpgsqlParameter<Int32>("id", NpgsqlTypes.NpgsqlDbType.Integer) { TypedValue = 123 });

Мой вопрос: первая команда эквивалентна второй (не будет значение int) или вместо него следует использовать второе?

Я думаю, что первое просто говорит Npg sql, какой тип данных использовать, но все равно будет содержать int.

Ответы [ 3 ]

1 голос
/ 28 января 2020

Основным преимуществом NpgsqlParameter перед AddWithValue является избегание бокса, поскольку AddWithValue принимает объект. Это означает, что каждый раз, когда вы передаете тип значения (int, double) в AddWithValue, вы получаете ненужное выделение кучи.

Что касается остального ... Я не знаю ни о каких других преимущества, связанные с выводом типа и производительностью, согласно ссылкам, размещенным выше. NpgsqlParameter принимает строго типизированный тип. NET, но Npg sql все равно должен выводить тип PostgreSQL из него. Например,. NET string может быть сопоставлен с PostgreSQL text, но также varchar или jsonb. Фактически вывод типа, происходящий внутри, идентичен, независимо от того, тип. NET определен в общем случае с помощью NpgsqlParameter или просто путем просмотра типа объекта, переданного в AddWithValue. Если вы хотите избежать логического вывода, вам нужно указать NpgsqlDbType - в том числе с NpgsqlParameter .

Обратите внимание, что я не знаю о существенных или общих проблемах производительности , связанных с к неверному выводу (как подразумевается в некоторых ссылках SQL Server). В большинстве случаев запрос просто не будет выполнен, потому что выведенный тип почему-то несовместим, но он довольно редко запускается медленно.

1 голос
/ 28 января 2020

Это на самом деле не подразумевается как ответ, так как я считаю, что мистер Харви сделал это достаточно, но это дольше, чем я могу добавить в комментарии, и у меня не будет форматирования ... поэтому заранее извиняюсь.

Прежде всего, пожалуйста, смотрите отзывы одного из авторов Npg sql о том, когда следует использовать обобщенный c API:

{ ссылка }

Кроме того, я не видел его в этом посте, но я также помню его комментарий, в котором указано, что одним из недостатков нового API является то, что он не переносим на другие адаптеры ADO. net, это означает, что если вы измените свой источник данных на Oracle, ожидайте, что это НЕ сработает.

Теперь, по моему горячему спортивному мнению ... Я видел, понимаю и согласен с обоснованием отказа от использования AddWithValue , Тем не менее, я буду первым, кто признает, что использую его. Причина в том, что это обычно работает, и я думаю, что имя метода очень прозрачно в отношении того, что он выполняет.

Два случая, когда я строго избегаю этого:

  • Объявить один раз назначьте много, как внутри транзакции, в которой вы выполняете несколько вставок, обновлений (или обновлений)
  • Даты. Так как Postre SQL имеет дату и временную метку, но. NET имеет только System.Datetime, AddWithValue, похоже, предполагает, что вы имеете в виду System.DateTime -> timestamp, из-за которого ваша программа будет рваться. В этом случае AddWithValue экономит немного, так как вам необходимо повторно объявить тип данных как дату

Это действительно работает для типов данных массива, что довольно фантастично c.

Итак, вы можете сделать это:

cmd.Parameters.Add(new NpgsqlParameter("FOO", NpgsqlDbType.Array | NpgsqlDbType.Varchar));
cmd.Parameters[0].Value = myArray;

или вы можете сделать:

cmd.Parameters.AddWithValue("FOO", myArray);

И это прекрасно работает ... Я действительно люблю PostgreSQL и Npg Sql.

0 голосов
/ 29 января 2020

После тщательного изучения информации, полученной от сообщества, мы решили go с NpgsqlParameter<T> с явным NpgsqlDbType.

Хотя мы согласны с тем, что снижение производительности действительно очень Трудно заметить оба варианта, а четкость объявления того, что вы передаете и во что вы хотите его преобразовать, убедила нас в go с чуть более многословным вариантом.

Большое спасибо всем, кто помогли!

...