2011-09-07 426 views
15

我有一个使用实体框架和SQL Server 2008(Express)数据库的应用程序。在对数据库中的实体进行更新时,我收到间歇性错误,指出'提供的值不是数据类型为float的有效实例'。但是,尽我所知,它设置的值始终是浮动的。他们是从整数投下的,但即使如此也总是会产生花车。如果代码确实设法创建了一个无效浮点数,我会认为.NET在它到达SQL Server之前就会抱怨它。实体框架SQL异常:提供的值不是数据类型的有效实例float

我已经在下面列出了完整的例外,代码提取和架构。

有什么我可以在这里丢失 - 例如,一个单一的值可以被认为是在.NET中的浮动,但不是在SQL Server中?另外,有没有什么办法可以以编程方式记录浮点的精度和范围,以便我可以诊断发生了什么问题,如果问题再次出现?

我已经添加了一些额外的日志记录以尝试捕获到底发生了什么,但这是一个间歇性问题,我不能自己复制它。

的错误是:

System.Data.UpdateException:更新条目中出现了错误。详情请参阅内部例外。 --->

System.Data.SqlClient.SqlException:传入的表格数据流(TDS)远程过程调用(RPC)协议流不正确。参数4(“@ 1”):提供的值不是数据类型为float的有效实例。检查源数据是否有无效值。无效值的一个例子是数值类型的数据,其比例大于精度。

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 

这里是正在执行的代码。 (请注意,图像类是实体框架的实体类)。

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列。

+0

SQL Server中的“float”映射到.NET中的“double”。这可能是你的问题吗?查看是否将代码中的Image.X和Image.Y更改为System.Double可修复此问题。 –

+0

啊,有趣的一点 - 我会试一试。尽管如此,我预计在.NET中使用float仍然可以,因为它是一个比double更小的类型,因此可以被铸造出来 - 但至少值得一试。我会看到会发生什么并发布更新... – John

+0

是的,当你写作的时候没错,但我猜,但EF在阅读时不知道该怎么做,所以无论如何它可能会抱怨。 –

回答

40

我得到了这个完全相同的错误。事实证明我正在将浮动除以零。这并没有在我执行这个部门的时候在代码中抛出异常;当我试图在数据库中保存这个值时,我得到了错误。

希望这对你们中的一些人阅读这个问题很有用 - 感谢约翰提高它。

+3

这是事实,但很难抓住,因为双重变成了'NaN'而不是崩溃,并给你一个零失败的分水岭!很难赶上。谢谢! – jocull

+0

同样的问题,但它实际上告诉我,我的值是'10a',但在仔细阅读Object Var对象列表后,它是NaN –

+0

当我保存了一个'ICollection '('public class DoubleValue {public virtual int Id { get; set;} public virtual double Value {get; set;}}'),并将DoubleValue属性初始化为double.NaN。 –

0

那么,你已经提到你正试图将int赋值为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