Int32.TryParse() или (int?) command.ExecuteScalar()

У меня есть SQL-запрос, который возвращает только одно поле — идентификатор типа INT.

И я должен использовать его как целое число в коде С#.

Какой способ быстрее и использует меньше памяти?

int id;
if(Int32.TryParse(command.ExecuteScalar().ToString(), out id))
{
  // use id
}

or

int? id = (int?)command.ExecuteScalar();
if(id.HasValue)
{
  // use id.Value
}

or

int? id = command.ExecuteScalar() as int?;
if(id.HasValue)
{
  // use id.Value
}

person abatishchev    schedule 23.07.2009    source источник
comment
Я знаю, что это старая, но актуальная цитата Дональда Кнута: «Программисты тратят огромное количество времени на размышления или беспокойства о скорости некритических частей своих программ, и эти попытки повысить эффективность на самом деле имеют сильное негативное влияние, когда отладка и обслуживание обдуманный. Мы должны забыть о малой эффективности, скажем, примерно в 97% случаев: преждевременная оптимизация — корень всех зол. Тем не менее, мы не должны упускать наши возможности в отношении этих критических 3%.   -  person Slothario    schedule 17.01.2017
comment
Привет @DannyNeumann, в общем, я не думаю, что имеет смысл публиковать это здесь, так как это вопрос 2009 года. В частности, написание эффективного кода по-прежнему важно. И вот как я научился это делать. Каждый день я вижу ужасный, ужасный код, который идеально подходит к цитате Кнута. При этом не следует тратить много времени на преждевременную оптимизацию некритичных частей, но в то же время не следует неэффективно писать некритичные части.   -  person abatishchev    schedule 17.01.2017


Ответы (7)


Разница между тремя мудрыми производительностью незначительна. Узким местом является перемещение данных из БД в ваше приложение, а не тривиальное приведение или вызов метода.

Я бы пошел с:

int? id = (int?)command.ExecuteScalar();
if(id.HasValue)
{
  // use id.Value
}

Он выходил из строя раньше, и если однажды люди изменят команду, чтобы она возвращала строку или дату, по крайней мере, произойдет сбой, и у вас будет возможность это исправить.

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

Обратите внимание: я обычно предпочитаю возвращать параметр out, чем выполнять скаляр выполнения, скаляр выполнения кажется хрупким (соглашение о том, что первый столбец в первой строке является возвращаемым значением, мне не подходит).

person Sam Saffron    schedule 23.07.2009
comment
ExecuteScalar() — это огромная победа в vb, где вы можете просто выполнить CInt() или CStr(). - person Joel Coehoorn; 24.07.2009

Если вы ожидаете, что команда вернет null, вы должны помнить, что база данных null (DBNull) — это не то же самое, что .NET null. Итак, преобразование DBNull в int? потерпит неудачу.

Я бы предложил следующее:

object result = command.ExecuteScalar();
int? id = (int?)(!Convert.IsDBNull(result) ? result : null);
person VladV    schedule 23.07.2009
comment
Имейте в виду, что если выполнение скаляра не возвращает ни одной строки, вы получите нуль. Вы правы, что если первая строка в первом столбце равна нулю, у вас могут быть проблемы. - person Sam Saffron; 24.07.2009
comment
но опять же это и ID (по крайней мере, я прочитал это как идентификатор/ключ), так что DBNull не проблема - person Rune FS; 24.07.2009
comment
@Sam Saffron, согласился с пустым набором строк. @Rune FS, мы не знаем здесь основной логики. Я бы не стал предполагать, может ли запрос вернуть null или нет, основываясь только на имени переменной. - person VladV; 24.07.2009
comment
@VladV согласился, что вам следует подумать об именах переменных, но я имел в виду тот факт, что это возвращаемый идентификатор (так сказано в вопросе), и поскольку идентификатор не соответствует идентификатору, а идентификатор в терминологии (MS) DB являются уникальными ненулевыми значениями либо вопрос неоднозначный, либо запрос не вернет DBNull :) - person Rune FS; 25.07.2009
comment
Не могли бы вы сократить это до int? id = (int?)command.ExecuteScalar() ?? null; ? - person Zorgarath; 25.10.2016

Если ничего из вышеперечисленного не работает (особенно для пользователей, которые борются с MySQL), почему бы вам не попробовать следующее?

int id = Convert.ToInt32(cmd.ExecuteScalar().ToString());
person hungrycoder    schedule 15.07.2012

int Result = int.Parse(Command.ExecuteScalar().ToString());

будет работать на С#.

person Sin    schedule 04.09.2012
comment
Это плохой подход: сначала сбрасывать в строку, а затем анализировать, когда объект уже является целым числом, его просто нужно привести. - person abatishchev; 04.09.2012

Последний. Convert.ToInt32() тоже вариант.

person Joel Coehoorn    schedule 23.07.2009
comment
Первый метод исходит от сатаны по многим причинам. Это медленнее и менее читабельно. Фу. - person Dave Markle; 24.07.2009
comment
Convert.ToInt32() работал у меня, тогда как приведение не работало с command.ExecuteScalar(); - person JYelton; 22.04.2010

Используйте id.HasValue для максимального крутого фактора Nullable Type!

person xyz    schedule 23.07.2009

person    schedule
comment
Это ответ? Или вы пытаетесь получить помощь? Потому что этот испанский комментарий означает 'Похоже, ошибка здесь, но я ее не вижу' - person brasofilo; 16.08.2014