SQL Server 2008(Express)データベースでEntityFrameworkを使用するアプリケーションがあります。データベース内のエンティティを更新しているときに、「指定された値がデータ型floatの有効なインスタンスではない」ことを示す断続的なエラーが発生します。ただし、私が知る限り、設定値は常に浮動小数点数になります。それらは整数からキャストされますが、それでも常に浮動小数点数を生成します。コードがなんとかして無効なfloatを作成できたとしたら、SQL Serverに到達する前に、.NETがそれについて文句を言うだろうと思っていたでしょう。
以下に、完全な例外、コードの抜粋、およびスキーマを含めました。
ここで欠落している可能性のあるものはありますか?たとえば、単一の値は.NETでは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を使用していることに注意してください。
これとまったく同じエラーが発生しました。フロートをゼロで割っていたことがわかりました。これは、分割を行った時点でコードに例外をスローしませんでした。この値をデータベースに保存しようとすると、エラーが発生しました。
これが質問を読んでいるあなたの何人かに役立つことを願っています-それを上げてくれてありがとうジョン。
さて、あなたはすでにintをfloatに割り当てようとしていると述べました。 1.0を掛けてfloatに変換してみてください。
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