2011-09-07 15 views
15

Ho un'applicazione che utilizza Entity Framework con un database SQL Server 2008 (Express). Durante l'aggiornamento di un'entità nel database viene visualizzato un errore intermittente che indica che "il valore fornito non è un'istanza valida del tipo di dati mobile". Tuttavia, come meglio posso dire, i valori che sta impostando saranno sempre float. Sono espressi da numeri interi, ma ancora produrranno sempre float. Se il codice fosse riuscito a creare un float non valido in qualche modo, avrei pensato che .NET si sarebbe lamentato prima che arrivasse persino a SQL Server.Eccezione SQL Entity Framework: il valore fornito non è un'istanza valida del tipo di dati float

Ho incluso l'eccezione completa, gli estratti di codice e lo schema di seguito.

C'è qualcosa che potrei mancare qui - per esempio, un singolo valore può essere considerato un float in .NET ma non in SQL Server? In alternativa, esiste un modo per registrare a livello di codice la precisione e la scala di un float in modo da poter diagnosticare cosa succede se il problema si ripresenta?

Ho aggiunto alcune registrazioni aggiuntive per provare a catturare esattamente cosa sta succedendo qui, ma questo è un problema intermittente e non riesco a riprodurlo da solo.

L'errore è:

System.Data.UpdateException: Si è verificato un errore durante l'aggiornamento delle voci. Vedi l'eccezione interna per i dettagli. --->

System.Data.SqlClient.SqlException: il flusso del protocollo RPC (Remote Procedure Call) della trasmissione remota di dati tabulari (TDS) non è corretto. Parametro 4 ("@ 1"): il valore fornito non è un'istanza valida del tipo di dati float. Controlla i dati di origine per i valori non validi. Un esempio di valore non valido è costituito da dati di tipo numerico con scala maggiore della precisione.

at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) 
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) 
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) 
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) 
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) 
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) 
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 
at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary`2 identifierValues, List`1 generatedValues) 
at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) 
--- End of inner exception stack trace --- 
at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) 
at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) 
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) 
at System.Data.Objects.ObjectContext.SaveChanges() 
at MyApplication.ImageProcessing.ProcessImage(Image image) in C:\Code\ImageProcessing.cs:line 224 

Ecco il codice che è in esecuzione. (Si noti che la classe immagine è la classe di entità da Entity Framework.)

private static System.Random _randomLocation = new System.Random(); 

private void ProcessImage(Image image) 
{ 
    float x = _randomLocation.Next(668); // note: the System.Random.Next method always returns an int 
    float y = 0 - image.Height; // note: image.Height is an int and is always around 300-600 in value in this application 

    image.X = x; 
    image.Y = y; 
    _dataContext.SaveChanges(); 
} 

L'estratto dello schema per la tabella che questo si riferisce è:

CREATE TABLE Image 
(
    ImageID uniqueidentifier NOT NULL PRIMARY KEY, 
    X float NOT NULL, 
    Y float NOT NULL 
) 

Anche Vorrei sottolineare che il modello EF usa il tipo di dati Single per le colonne X e Y.

+0

"float" in SQL Server esegue il mapping a "double" in .NET. Potrebbe essere il tuo problema? Verifica se la modifica di Image.X e Image.Y nel codice su System.Double risolve il problema. –

+0

Ah, punto interessante - ci provo. Anche se, mi sarei aspettato che l'uso di float in .NET sarebbe comunque soddisfacente dato che è un tipo più piccolo del doppio e quindi potrebbe essere scartato, ma vale la pena provare almeno. Vedrò cosa succede e postare un aggiornamento ... – John

+0

Sì, quando si sta scrivendo sarebbe ok, credo, ma EF non saprebbe cosa fare quando sta leggendo, quindi potrebbe lamentarsi a prescindere. –

risposta

40

Ho ottenuto esattamente lo stesso errore. Risulta che stavo dividendo un galleggiante per zero. Questo non ha fatto un'eccezione nel codice nel momento in cui ho fatto la divisione; quando ho provato a salvare questo valore nel database ho ricevuto l'errore.

Spero che questo sia utile per alcuni di voi che leggono la domanda - Grazie John per averlo sollevato.

+3

Questo è vero, ma è difficile da catturare perché il doppio diventa 'NaN 'invece di crash e ti dà un errore di divisione per zero! Molto difficile da catturare. Grazie! – jocull

+0

Stesso problema ma in realtà mi stava dicendo che il mio valore era '10a' ma dopo aver esaminato i valori var di Elenco di oggetti era NaN –

+0

Ho ottenuto questo quando salvavo un 'ICollection ' ('publicVeclass DoubleValue {public virtual int Id { get; set;} public virtual double Value {get; set;}} '), e la proprietà DoubleValue è stata inizializzata in double.NaN. –

0

Bene, hai già detto che stai provando ad assegnare a flo il float. Prova a convertirlo in float moltiplicandolo per 1.0.

float x = _randomLocation.Next(668); // note: the System.Random.Next method always returns an int 
    float y = 0 - image.Height; // note: image.Height is an int and is always around 300-600 in value in this application 
Problemi correlati