2012-10-01 9 views
6

Tengo este problema, tengo una mesa para comprascadena Convertir a int en una consulta LINQ Marco de la entidad y el manejo de la excepción análisis

Purchases(Date DateTime, Number string) 

lo que quiero es crear un nuevo registro, por lo que necesito Max (Número), el problema aquí es que el número es una cadena, lo he intentado

Purchases.Select(X=>int.Parse(X.Number)).Max() 

pero podría lanzar una excepción, he crear una extensión personalizada ToInt() así que cuando utilizo

Purchases.Select(X=>X.Number.ToInt()).Max() 

lanza una excepción diciendo que mi Toint() no se puede utilizar con consulta LINQ mismo que el famoso ToString()

por lo que mi pregunta es: ¿hay una manera de convertir una cadena int en la consulta linq & manejando excepciones al mismo tiempo o para integrar funciones personalizadas a una consulta linq !!

y esto es mi extensión

public static int ToInt(this string s) 
    { 
     try 
     { 
      return int.Parse(s); 
     } 
     catch 
     { 
     } 
     return 0; 
    } 
+4

¿Alguna razón por la cual el campo 'Number' está declarado como' string' en su tabla? –

+0

¿Podemos ver la extensión que ha creado? –

+0

¿Cómo manejas si se lanza una excepción? continúa sumando o deteniendo? –

Respuesta

10

Primera forma:

var numbers = Purchases.Select(x => x.Number).ToList(); 

int temp; 
int max = numbers.Select(n => int.TryParse(n, out temp) ? temp : 0).Max(); 

Console.WriteLine("Max: {0}", max); 

Segunda forma:

int temp2; 
int max2 = Purchases.Select(x => x.Number).ToList().Select(n => int.TryParse(n, out temp2) ? temp2 : 0).Max(); 

Console.WriteLine("Max 2: {0}", max2); 

La clave es la .ToList() en esos dos maneras. Obtiene todos los datos string de la base de datos, por lo que cuando llama al int.TryParse en los resultados, la consulta de la base de datos ya se ha ejecutado, por lo que usa código CLR puro y no intenta convertir int.TryParse en una consulta SQL. Hice un contexto EF en uno de mis proyectos de Sandbox y verifiqué que funciona.

+1

siempre debe agregar 'DefaultIfEmpty' no queremos ver otra excepción – S3ddi9

+0

' int.TryParse' no arrojará una excepción. El ternario le proporciona su valor predeterminado si 'int.TryParse' devuelve' false', lo que significa que la conversión falló. – Gromer

+0

También puede usar variaciones en esas consultas para descubrir cuáles no se convierten. 'int temp3; var noConvert = Purchases.Select (x => x.Number) .ToList(). Where (n => int.TryParse (n, out temp3) == false); ' – Gromer

2

No entiendo por qué no desea que la excepción, ya que si no pasó la fundición, entonces significa que algo malo le pasó a su aplicación (o, al menos, así que lo entiendo). Tampoco entiendo por qué guardar lo que se supone que es un número como una cadena en la base de datos. Por lo general, lo mantendrás como un número para que no tengas que lidiar con problemas como este más adelante, y si alguien intenta insertar un valor incorrecto, fallarás en la inserción.

PERO - si desea hacer que esta línea funcione, debe usar int.TryParse que le devolverá verdadero si el valor arrojado con éxito y pondrá el valor en miembro 'fuera' que estará fuera de la consulta. como este:

int tmp; 
Purchases.Select(X=>int.TryParse(X.Number, out tmp) ? tmp : 0).Max() 

y en lugar de "0" poner un valor predeterminado que no ensucie con su lógica.

+0

esa es muy inteligente muy, muy buena respuesta !!! – S3ddi9

+4

No puede usar 'int.TryParse' en una consulta _EF_. Obtendrá esto: 'Excepción no controlada: System.NotSupportedException: LINQ to Entities no reconoce el método 'Boolean TryParse (System.String, Int32 ByRef)', y este método no se puede traducir a una expresión de tienda. ' – Gromer

+0

sí, eso es right – S3ddi9

Cuestiones relacionadas