2011-08-30 7 views
6

tengo la siguiente declaración de LINQ:C# Convert.ToDouble (valor) en la Declaración de Lambda LINQ

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

El q.Value es un valor de cadena de un doble, y value es también un valor de cadena de un doble, tanto de estos deben convertirse a dobles para que puedan ser comparados por igualdad.

Cuando elimino errores sobre esta declaración de LINQ, me estoy haciendo la siguiente excepción de SQL:

error en la conversión de tipo de datos varchar a flotar

No estoy seguro de por qué no está permitiendo que haga esto, pero me pregunto cuál es la solución, necesito comparar mis dos valores para la igualdad aquí.

Respuesta

7

Para empezar, me gustaría extraer el Convert.ToDouble(value) a cabo a una variable local:

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

Es muy posible que es el intento de conversión de value ese es el problema, más que el intento de conversión de q.Value por alguna fila . Alternativamente, podría ser que tienes una fila que no tiene un valor válido. (Se podría tratar usando double.TryParse pero no estoy seguro de lo bien que eso GIONG a trabajar ...)

Sin embargo, es también generalmente una mala idea comparar los valores de punto flotante binario con la igualdad simple en la primera lugar. Es posible que desee usar algún grado de tolerancia (y exactamente cómo funciona eso con LINQ to SQL es otra cuestión ...)

+0

Es más que posible tratar de realizarlo en SQL - es 100% absolutamente cierto (ver el mensaje de error) – Jeff

+0

@ JeffN825: Mi punto es que es posible que el intento de realizar la conversión del valor "fijo" es el problema, no el intento de convertir los datos que están en la base de datos. Editará para aclarar. –

+0

Para mi propia educación, ¿por qué es malo comparar dobles? Debido al viejo problema "decimal"? (http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems) – Jeff

0

Parece que está utilizando LINQ to SQL. Ese error proviene directamente del servidor SQL que ejecuta la consulta (no su código). Supongo que tiene ALGUNA fila con un Valor que no es un valor numérico válido.

Me ejecutar la consulta siguiente en SSMS y creo que usted es encontrar falla con el error

Error Converting data type varchar to float 

select convert(float, value) from leaddata 

EDIT:

Si desea añadir un poco de tolerancia a fallos que sugiere Jon, se se pudo asignar la función IsNumeric y hacer el siguiente:

En su DBML (referencia 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> 

En su código:

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

Me gusta esta solución, la desventaja es que Items es un IQueryable así que ¿tendré acceso a esta función? – TheJediCowboy

+0

Una vez que lo mapea en su DBML, debe generar la función IsNumeric en su DataContext. – Jeff

+0

Si desea declararlo completamente independiente de su DataContext, agregue al DBML, pero asigne un método estático como aquí http://msdn.microsoft.com/en-us/library/bb386973.aspx – Jeff

0

Compruebe que los valores de cadena que está convirtiendo a float en SQL Server son válidos (por ejemplo, que no están en blanco o tienen un símbolo válido para el punto decimal).

0

Parece que uno de los valores no se puede convertir con éxito en un flotador.