ExecuteNonQuery возвращает -1 при использовании sql COUNT, несмотря на строку запроса

По какой-то причине ExecuteNonQuery() в C# возвращает -1, хотя, когда я запускаю запрос отдельно, значение возвращает фактическое необходимое значение.

Например:

try
{

    var connString ="Data Source=ServerName;InitialCatalog=DatabaseName;Integrated Security=true;"
    SqlConnection conn = new SqlConnection(connString);

    SqlCommand someCmd = new SqlCommand("SELECT COUNT(*) FROM SomeTable");

    someCmd.Connection = conn;

    conn.Open();

    var theCount = cmd.ExecuteNonQuery();

    conn.Close();
}
catch(Exception ex)
{
    Console.WriteLine(ex.Message);
}

Когда команда выполняется, она возвращает -1. Хотя если запустить запрос отдельно,

SELECT COUNT(*) FROM SomeTable;

Столбец возвращает одну строку со значением 4, если запрашиваемая таблица содержит 4 строк.


person JDavila    schedule 27.06.2016    source источник
comment
Возможный дубликат ExecuteNonQuery for SELECT SQL-оператора, не возвращающего строк   -  person Orel Eraki    schedule 27.06.2016


Ответы (2)


На основе MSDN:

Для инструкций UPDATE, INSERT и DELETE возвращаемое значение — это количество строк, затронутых командой. Если для вставляемой или обновляемой таблицы существует триггер, возвращаемое значение включает в себя количество строк, затронутых операцией вставки или обновления, и количество строк, затронутых триггером или триггерами. Для всех остальных типов операторов возвращаемое значение равно -1. Если происходит откат, возвращаемое значение также равно -1.

Вы хотите вернуть количество строк, затронутых командой, и сохранить его в переменной int, но, поскольку тип оператора select, он возвращает -1.

Решение. Если вы хотите получить количество строк, затронутых командой SELECT, и сохранить его в переменной int, вы можете использовать ExecuteScalar.

var theCount = (int)cmd.ExecuteScalar();
person Salah Akbari    schedule 27.06.2016
comment
Хороший ответ, стоит упомянуть особенности ExecuteScaler из MSDN Executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored. - person dougajmcdonald; 27.06.2016
comment
Спасибо! Это сработало отлично! Мне придется поискать ExecuteScaler в MSDN, так как я не знаком с синтаксисом (int) перед cmd.ExecuteScalar(); - person JDavila; 27.06.2016
comment
Это работает с небольшой модификацией: результат, который я получаю, long, а не int, попытка приведения к int вызывает исключение. - person Soonts; 02.06.2021

Вы можете использовать ядро ​​Ef с Ado.net, как в этом примере.

var context = new SampleDbContext();
using (var connection = context.Database.GetDbConnection())
{
    connection.Open();

    using (var command = connection.CreateCommand())
    {
        command.CommandText = "SELECT COUNT(*) FROM SomeTable";
        var result = command.ExecuteScalar().ToString();
    }
}
person Mohammad Daliri    schedule 08.03.2018