私のコードは次のとおりです。C#とEntity Frameworkを使用して小さなフロート値をSQL Serverに挿入する
public class MyDbContext : DbContext
{
public virtual DbSet<CurrentData> CurrentData { get; set; }
}
public class CurrentData
{
public int ID { get; set; }
public DateTime Time { get; set; }
public float Value { get; set; }
}
...
float f = 1.37E-40f;
using (var context = new MyDbContext())
{
var data = new CurrentData() { ID = 100, Time = DateTime.Now, Value = f };
context.CurrentData.Add(data);
var result = context.SaveChanges();
}
float値が小さいため、SaveChanges()
で例外が発生します。
着信表形式データストリーム(TDS)リモートプロシージャコール(RPC)プロトコルストリームが正しくありません。パラメーター4(\ "@ 1 \"):指定された値は、データ型realの有効なインスタンスではありません。ソースデータに無効な値がないかチェックしてください。無効な値の例は、精度より大きいスケールを持つ数値型のデータです。
f
を0に変更すると、正常に動作します。
SQL ServerのREAL
タイプ範囲を確認したとき、正の最小値は1.18E-38です。
https://msdn.microsoft.com/en-us/library/ms173773.aspx
C#でfloat値が1.18E-38よりも小さいのであれば、例外が発生します。
私はこの
if (f > 0 && f < 1.18E-38f)
f = 0;
else if (f < 0 && f > -1.18E-38f)
f = 0;
ようf
値を変更しかし、私はそれが良い見ていないと思います。
もっと良い解決策はありますか?
私は、Entity FrameworkではなくSqlDataAdapter
を使用してテストしましたが、同じ例外がありました。
REAL
を持っているようですねEFのv6.1.3およびSQL Server 2012
「数字」のみを格納し、mssqlの数値を計算する必要がない場合は、文字列リテラルとして格納することができますか? https://msdn.microsoft.com/en-us/library/sd9e25kz(v=vs.110).aspx – montewhizdoh
@montewhizdohそうする必要はないからです。 SQL Server *は、スケールと精度がよく定義された '数値型 'を持っています(例:' numeric(19,5) ')。 –
'' float'または 'real'を使ってはいけません。テーブルに必要な位取りと精度を持つ数値型を使用し、クラスに 'decimal'を使用します。一方、*なぜ*あなたはそのような小さな番号を使用したいですか? NULLをエミュレートしようとしていますか? –