2011-09-07 59 views
15

Tengo una aplicación que utiliza Entity Framework con una base de datos SQL Server 2008 (Express). Recibo un error intermitente al hacer una actualización de una entidad en la base de datos que indica que 'el valor suministrado no es una instancia válida del tipo de datos flotante'. Sin embargo, lo mejor que puedo decir es que los valores que establece siempre serán flotantes. Están emitidos a partir de enteros, pero aún así siempre darán flotas. Si el código se las arregló para crear una flotación no válida de alguna manera, habría pensado que .NET se quejaría antes incluso de llegar a SQL Server.Entity Framework Excepción de SQL: el valor proporcionado no es una instancia válida del tipo de datos float

He incluido la excepción completa, extractos de código y esquema a continuación.

¿Hay algo que podría estar perdiendo aquí? Por ejemplo, ¿se podría considerar que un solo valor es flotante en .NET pero no en SQL Server? De forma alternativa, ¿hay alguna manera de registrar programáticamente la precisión y la escala de un flotador para que pueda diagnosticar lo que está sucediendo si surge el problema otra vez?

He agregado algunos registros adicionales para intentar capturar exactamente lo que está sucediendo aquí, pero este es un problema intermitente y no puedo reproducirlo yo mismo.

El error es:

System.Data.UpdateException: Se ha producido un error al actualizar las entradas. Ver la excepción interna para más detalles. --->

System.Data.SqlClient.SqlException: La secuencia de protocolo de llamada a procedimiento remoto (RDS) de flujo de datos (TPC) es incorrecta. Parámetro 4 ("@ 1"): el valor proporcionado no es una instancia válida del tipo de datos float. Verifique los datos de origen para valores inválidos. Un ejemplo de un valor no válido son los datos de tipo numérico con una escala mayor que la precisión.

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 

Aquí está el código que está siendo ejecutado. (Tenga en cuenta que la clase La imagen es la clase de entidad de 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(); 
} 

El extracto esquema de la tabla que esto se refiere es:

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

también deben tener en cuenta que el modelo de EF usa el tipo de datos Individual para las columnas X e Y.

+0

"flotante" en los mapas de SQL Server a "doble" en .NET. ¿Podria ese ser tu problema? Vea si cambiar Image.X e Image.Y en su código a System.Double corrige el problema. –

+0

Ah, punto interesante - Voy a intentarlo. Aunque, hubiera esperado que usar float en .NET estaría bien ya que es un tipo más pequeño que el doble y así podría ser lanzado, pero al menos vale la pena intentarlo. Veré qué sucede y publicaré una actualización ... – John

+0

Sí, cuando creo que estás escribiendo estarías bien, pero EF no sabría qué hacer cuando está leyendo, por lo que podría quejarse independientemente. –

Respuesta

40

Tengo este mismo error exacto. Resulta que estaba dividiendo un flotador por cero. Esto no arrojó una excepción en el código en el momento en que hice la división; cuando intenté guardar este valor en la base de datos, recibí el error.

Espero que esto les resulte útil a algunos de ustedes que leen la pregunta - Gracias John por haberlo planteado.

+3

Esto es cierto, pero es difícil de detectar porque el doble se convierte en 'NaN' en lugar de estrellarse y ¡te da una falla de división por cero! Muy difícil de atrapar ¡Gracias! – jocull

+0

Mismo problema pero en realidad me decía que mi valor era '10a', pero después de leer detenidamente los valores de var de la Lista de Objetos era NaN –

+0

Lo obtuve al guardar un 'ICollection ' ('public class DoubleValue {public virtual int Id { get; set;} public double virtual Value {get; set;}} '), y la propiedad DoubleValue se inicializó en double.NaN. –

0

Bueno, ya mencionaste que estás tratando de asignar int a float. Intenta convertir eso en flotar multiplicando por 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 
Cuestiones relacionadas