Entity Framework SQL Exception: поставляемое значение не является допустимым экземпляром типа данных float

У меня есть приложение, использующее Entity Framework с базой данных SQL Server 2008 (Express). Я получаю прерывистую ошибку при выполнении обновления для сущности в базе данных, которая указывает, что "поставляемое значение не является допустимым экземпляром типа данных float". Однако, насколько я могу судить, значения, которые он устанавливает, всегда будут плавать. Они отлиты из целых чисел, но даже по-прежнему будут давать поплавки. Если бы код действительно каким-то образом создал некорректный float, я бы подумал, что .NET будет жаловаться на него до того, как он даже попадет на SQL Server.

Я включил полное исключение, выдержки из кода и схему ниже.

Есть ли что-нибудь, что я мог бы здесь пропустить - например, можно ли считать одно значение float в .NET, но не в SQL Server? В качестве альтернативы, можно ли каким-либо образом программно регистрировать точность и масштаб поплавка, чтобы я мог диагностировать, что происходит, если проблема снова возникает?

Я добавил несколько дополнительных журналов, чтобы попытаться точно зафиксировать, что происходит здесь, но это проблема с прерывистой ситуацией, и я не могу воспроизвести ее сам.

Ошибка:

System.Data.UpdateException: при обновлении записей произошла ошибка. Подробнее см. Внутреннее исключение. --- >

System.Data.SqlClient.SqlException: поток протокола входящего потока табличных данных (TDS) удаленных процедур (RPC) неверен. Параметр 4 ( "@1" ): поставляемое значение не является допустимым экземпляром типа данных с плавающей точкой. Проверьте исходные данные на недопустимые значения. Примером недопустимого значения являются данные числового типа со шкалой, превышающей точность.

 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

Здесь выполняется код, который выполняется. (Обратите внимание, что класс Image является классом сущности из 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();
}

Вывод схемы для таблицы, на который это ссылается, это:

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

Также следует отметить, что модель EF использует тип данных Single для столбцов X и Y.

Ответы

Ответ 1

У меня такая же ошибка. Оказывается, я делят поплавок на ноль. Это не вызвало исключения в коде во время моего разделения; когда я попытался сохранить это значение в базе данных, я получил ошибку.

Надеюсь, что это полезно для некоторых из вас, читающих вопрос - спасибо Джону за его поднятие.

Ответ 2

Ну, вы уже упоминали, что вы пытаетесь присвоить int float. Попробуйте преобразовать его в float, умножив на 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