2016-05-20 18 views
6

In meiner Datenbank habe ich NextStatDistanceTime Wert als Float. Wenn "float time = reader.GetFloat(0);" Linie excecuted, gibt es einen Fehler vonWie Float-Wert mit SqlDataReader erhalten?

System ungültig Guss Ausnahme

Wie kann ich Float-Wert von SQL-Befehl in diesem Code erhalten?

Hier ist mein Code:

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); 
     } 
    } 

} 
+3

Was ist der Typ in der Datenbank? –

+0

@JonSkeet er hat es erwähnt, seine "float" in der Datenbank. –

+1

@RanjitSingh: Whoops, verpasst das. In diesem Fall würde ich wirklich erwarten, dass es in Ordnung ist ... Meine Vermutung ist, dass es nicht wirklich ein Float in der Datenbank ist. Es wäre interessant, das Ergebnis des Aufrufs von 'reader.GetValue (0)' zu kennen - welcher Typ ist das? –

Antwort

12

Es ist Zeit für einen kleinen Tisch, glaube ich.

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

Beachten Sie, dass GetFloat den falschen Namen hat - es GetSingle sein sollte, weil float ein -spezifische Name C# ist. In VB.NET zum Beispiel macht es keinen Sinn. Wenn Ihre Datenbankspalte vom Typ FLOAT ist, lesen Sie sie mit GetDouble, nicht GetFloat. Die Datenlesemethoden tun nicht führen Konvertierungen durch; Es gibt eine generische GetValue Methode, um den Wert als object zu erhalten, den Sie dann weiter konvertieren können.

Übrigens ist dies nicht die einzige Subtilität - die.NET-Gleitkommatypen unterstützen denormalized values, wohingegen die T-SQL-Typen dies nicht tun. Daher ist es möglich, Gleitkommazahlen in Ihrem .NET-Code zu verwenden, die nicht erfolgreich in der Datenbank gespeichert werden können, selbst wenn die Typen übereinstimmen.

+0

Sie finden die Tabelle [hier] (https://msdn.microsoft.com/en-us/library/ms131092 (v = sql.130) .aspx) ;-) –

+0

@TimSchmelter: das ist ein Subtil verschiedene Tabelle, weil es auch die Zuordnung zu den SQL-spezifischen ADO.NET-Typen beschreibt. 'SqlSingle' ist nicht dasselbe wie' System.Single'. Ich könnte es der Vollständigkeit halber in meine Tabelle aufnehmen, aber diese Typen müssen selten verwendet werden, es sei denn, es gibt keinen entsprechenden .NET-Systemtyp (wie 'SqlGeography'). Aber, ja, dies ist eine weitere Ebene von Conversions, auf die Sie achten sollten. –

0

Sie versuchen können:

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

beachten Sie auch (wenn auch nicht mit Ihrem Q bezogen), die Sie brauchen nicht zu laufen

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

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

Versuchen Sie dies, das wird die Zeit f bekommen aus der Datenbank dann wandeln Sie es in einen Float um, können Sie einfach die reader["NextStatDistanceTime] in die tryparse setzen, wenn Sie wollen, aber um es klarer zu machen, habe ich es so gemacht.

mich Alle Probleme

+2

Dies ist eine unnötige Problemumgehung. –

+0

@TimSchmelter erklären? – Brendon

+0

Siehe zum Beispiel die Antwort von @Hari Prasad. Keine Notwendigkeit für diese Arbeit herum. –

0

Versuchen Sie, diese

convert.ToSingle(reader["NextStatDistanceTime"]) 

oder

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

Float von SQL wissen lassen äquivalent von C# zu verdoppeln, können Sie die ähnliche Abbildung sehen here

0

Wahrscheinlich stimmt die Genauigkeit nicht überein zwischen Datenbanktyp und C# -Typ. Versuchen Sie werfen wie (float)reader.GetDouble(0);

1

Meine Vermutung ist, dass Datenbank doppelten Wert zurückgibt, versuchen Sie es als Double bekommen und wandeln es float (falls erforderlich).

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

Wie Sie here eine SQL-Server-float Karten in ein .NET-Doppel lesen können, so dass Sie GetDouble verwenden müssen:

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 
}