Как получить значение 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);