Как получить значение float с помощью SqlDataReader?

в моей базе данных у меня есть значение NextStatDistanceTime как float. Когда"float time = reader.GetFloat(0); " линия исключена, она дает ошибку

системное недопустимое исключение cast

Как я могу получить значение float из команды sql в этом коде?

вот мой код:

using (SqlConnection conn = new SqlConnection(@"<myconnectionstring>"))
{
    float totaltime = 0;
    for (int i = startStationIndex; i < endStationIndex; i++)
    {
        SqlCommand command = new SqlCommand("SELECT NextStatDistanceTime FROM [MetroDatabase].[dbo].[MetroStation] WHERE StationIndex = " + i + "", conn);
        try
        {
            conn.Open();
            command.ExecuteNonQuery();
            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    float time = reader.GetFloat(0);
                    totaltime = totaltime + time;
                    conn.Close();
                }
            }                        
        }
        catch (Exception ex)
        {
            result = ex.Message;
            Console.WriteLine(ex.Message);
        }
    }

}

7 ответов


пришло время для маленького столика, я думаю.

T-SQL type name | .NET equivalent | C# type name | DataReader method
----------------+-----------------+--------------+------------------------
FLOAT           | System.Double   | double       | IDataReader.GetDouble()
REAL            | System.Single   | float        | IDataReader.GetFloat()

отметим, что GetFloat имеет неправильное имя -- это должно быть GetSingle, потому что float - это имя, специфичное для C#. Нет смысла в VB.NET к примеру.

Итак, если ваш столбец базы данных имеет тип FLOAT, прочитать его с помощью GetDouble, а не GetFloat. Методы чтения данных не выполнить преобразования; есть общий GetValue метод, чтобы получить значение как object что вы можете конвертировать дальше.

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


Как вы можете прочитать здесь SQL-server float сопоставляется с .NET double, поэтому вам нужно использовать GetDouble:

double totaltime = 0;  // necessary, double is wider than float
// ...

while (reader.Read())
{
    double time = reader.GetDouble(0);
    totaltime = totaltime + time;
    // conn.Close(); no, not in this loop, should be closed in the finally or via using-statement
}

Я предполагаю, что база данных возвращает двойное значение, попробуйте получить его как Double и преобразовать его float (Если требуется).

float time= (float) reader.GetDouble(0);

можно попробовать:

float time = float.Parse(reader[0].ToString());

также обратите внимание (хотя и не связано с вашим Q), что вам не нужно запускать

command.ExecuteNonQuery();

попробуй такое

convert.ToSingle(reader["NextStatDistanceTime"])

или

double value = (double)reader["NextStatDistanceTime"]

Float sql эквивалентен двойному c#, вы можете увидеть подобное сопоставление здесь


 while (reader.Read())
 {
     object initialTime = reader["NextStatDistanceTime"];
     float time;
     float.TryParse(initialTime.ToString(), out time);

     totaltime = totaltime + time;
     conn.Close();
 }

попробуйте это, это получит время из базы данных, а затем преобразует его в float, вы можете просто поместить reader["NextStatDistanceTime] в tryparse, если хотите, но чтобы было яснее, я сделал это так.

любые вопросы, дайте мне знать


вероятно, это несоответствие точности между типом базы данных и типом c#. Попробуйте бросить как (float)reader.GetDouble(0);