2011-08-30 1 views
6

私は、次のLINQ文を持っている:両方、C#Convert.ToDouble(値)

Items = Items.Where(p => p.LeadDatas.Any(
         q => 
         q.LeadField.Name == descriptor.Name && 
         Convert.ToDouble(q.Value) == Convert.ToDouble(value))); 

q.Valueは、二重の文字列値であり、valueも、二重の文字列値であり、これらは、平等のために比較できるように倍に変換する必要がありました。私はこのLINQ文の上でデバッグするときに

、私は次のSQLExceptionを取得しています:

をフロートするデータ型varchar型の変換

エラーは、私は私が行うことを許可されていない理由はわかりませんこれは、しかし、私は修正が何であるか疑問に思っています、私は私の2つの値をここで平等のために比較する必要があります。私はローカル変数に出Convert.ToDouble(value)を抽出します、で開始する

答えて

7

double target = Convert.ToDouble(value); 
Items = Items.Where(p => p.LeadDatas.Any(q => 
          q.LeadField.Name == descriptor.Name && 
          Convert.ToDouble(q.Value) == target)); 

それはそれは問題だvalueの未遂変換ではなく、いくつかの行のq.Valueの未遂変換だと、かなり可能です。あるいは、有効な値を持たない行がある可能性があります。最初に簡単な等式と2進浮動小数点値を比較する

しかし、それはまた、は、一般的です悪い考えを(...あなたはdouble.TryParseを使用してを試みることができるが、私はそれが動作するようにgiongだどれだけわかりません)場所。ある程度の許容度を使用することができます(そして、LINQ to SQLで動作する方法は別の問題です...)

+0

それはSQLでそれを実行しようとしている可能性があります - それは100%確実です(エラーメッセージを参照) – Jeff

+0

@ JeffN825:私の指摘は、データベース内のデータを変換しようとするのではなく、問題です。明確にするために編集します。 –

+0

私自身の教育のために、なぜ倍を比較するのが悪いですか?年齢の古い "小数"の問題のために? (http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems) – Jeff

0

LINQ to SQLを使用しているようです。このエラーは、(コードではなく)クエリを実行しているSQL Serverから直接発生しています。私の推測では、有効な数値ではないValueを持つ行がいくつかあるということです。

私はSSMSで、次のクエリを実行しますと、私はあなたがそれがエラーで失敗見つけるだと思う

Error Converting data type varchar to float 

select convert(float, value) from leaddata 

EDIT:

あなたはジョンが示唆したように、いくつかのフォールトトレランスを追加したい場合は、 IsNumeric関数の機能をマッピングし、下記行うことができます:あなたのDBML(参照How to know if a field is numeric in Linq To SQL

<Function Name="ISNUMERIC" IsComposable="true"> 
    <Parameter Name="Expression" Parameter="Expression" Type="System.String" DbType="NVarChar(4000)" /> 
    <Return Type="System.Boolean" DbType="BIT NOT NULL"/> 
</Function> 

あなたのコードで

double target = Convert.ToDouble(value); 
Items = Items.Where(p => p.LeadDatas.Where(i => myDataContext.IsNumeric(i)).Any(q => 
          q.LeadField.Name == descriptor.Name && 
          Convert.ToDouble(q.Value) == target)); 
+0

私はこのソリューションが気に入っていますが、欠点は、アイテムがIQueryable なので、この機能にアクセスできますか? – TheJediCowboy

+0

DBMLにマップすると、DataContextにIsNumeric関数が生成されます。 – Jeff

+0

DataContextから完全に独立して宣言したい場合は、DBMLに追加しますが、ここのような静的メソッドにマップしてください。http://msdn.microsoft.com/en-us/library/bb386973.aspx – Jeff

0

チェックを使用すると、SQL Serverでfloatに変換する文字列値が有効であることを確認するために(例えば、彼らは空白ではないか、彼らは、小数点の有効なシンボルを持っています)。

0

値の1つが浮動小数点に変換できないようです。