2011-09-07 51 views
15

SQL Server 2008(Express)データベースでEntity Frameworkを使用するアプリケーションがあります。私は、データベース内のエンティティへの更新を実行中に断続的なエラーが発生しています。これは、 '指定された値がデータ型floatの有効なインスタンスではないことを示します。'しかし、私が知る限り、設定されている値は常に浮動小数点になります。彼らは整数からキャストされますが、それでもなお浮動小数点を生成します。コードが無効な浮動小数点数を何らかの形で作成できたなら、.NETがSQL Serverに到達する前にそれについて文句を言うだろうと思っていただろう。Entity Framework SQL例外:指定された値がfloatデータ型の有効なインスタンスではありません

完全な例外、コード抽出、およびスキーマを以下に示しました。

ここで欠けているものはありますか。たとえば、.NETでは1つの値がfloatとみなされますが、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 

ここで実行されているコードです。 (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モデルXおよびY列にデータ型Singleを使用します。

+0

SQL Serverの "float"は.NETの "double"にマップされます。それはあなたの問題だろうか?コード内のImage.XとImage.YをSystem.Doubleに変更することで問題が解決されるかどうかを確認してください。 –

+0

ああ、面白い点 - 私はそれを試してみましょう。しかし、.NETでfloatを使用すると、double型よりも小さな型であり、キャストアップすることができるため、まだ有効ですが、少なくとも試してみる価値はあります。何が起こるかを見て、アップデートを投稿します... – John

+0

あなたが書いているときにうんざりしているのは大丈夫だろうと思うが、EFは読んでいるときに何をすべきか分からないので、それは無関係かもしれない。 –

答えて

40

このエラーはまったく同じです。私はフロートを0で割っていたことが分かります。これは私が部門をした時のコードに例外を投げなかった。この値をデータベースに保存しようとしたときにエラーが発生しました。

これはあなたが質問を読んでいる人には役に立ちます。

+3

これは当てはまりますが、衝突するのではなく、二重が「NaN」になり、ゼロの失敗で分裂するため、捕まえにくいです!捕まえるのが非常に難しい。ありがとう! – jocull

+0

同じ問題ですが、実際に私の値が '10a'だったと私に伝えていましたが、オブジェクトの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 
関連する問題