2012-02-22 33 views
6

He la siguiente tabla:LINQ obtener el valor máximo de la lista

ID Amt Received 
-- ---- -------- 
2 55 N 
2 88 Y 
2 44 N 
3 5 N 
3 9 N 
4 5 N 
5 33 Y 
6 43 N 
7 54 N 

    var result = (from rs in db.Exp 
        where rs.ID == id 
        && rs.Received == true 
        select rs).Max().Any(); 

Dada una identificación, que necesito para encontrar el máximo Amt para un identificador dado y luego comprobar si es Y, si es así, devolver verdadero else devuelve falso.

Respuesta

18

Esto debería hacerlo;

db.Exp. 
    Where(x => x.ID == id). 
    OrderByDescending(x => x.Amt). 
    Take(1). 
    Any(x => x.Received == "Y"); 
+0

Agradable. Sospecho que la última parte debería ser 'x => x.Received', pero me gusta la forma en que maneja los resultados vacíos. –

+0

@Joachim Isaksson - Me gusta la solución. Necesito agregar otra condición al .Any (x => x.Received == "Y" && x => x.División == "Contabilidad") pero no me deja hacerlo. Alguna idea de por qué. Tenga en cuenta que División no está en la tabla anterior. Me olvidé de incluirlo –

+0

@NatePet Solo necesita incluir 'x =>' una vez en una lambda, por lo que debería ser '.Any (x => x.Received ==" Y "&& x.Division ==" Accounting ")' –

3

Tiene que decir lo que quiere el Max de.

var result = 
    (from rs in db.Exp 
    where rs.ID == id && rs.Received 
    select rs) 
    .Max(row => row.Amt) == Y; 

Y no es necesario en absoluto el .Any()

0
// "I need to find the max Amt for a given id..." 
var elementWithMaxAmount = 
    db.Exp 
    .Where(x => x.ID == id) 
    .OrderByDescending(x => x.Amount) 
    .FirstOrDefault(); 

// "... and then check if it is Y" 
var result = (elementWithMaxAmount != null && 
       elementWithMaxAmount.Received == "Y"); 
6

Desafortunadamente LINQ no proporciona un "máximo por un atributo" método. MoreLINQ lo hace con su operador MaxBy, pero eso no se puede traducir a SQL, por supuesto. Entonces, si se trata de una consulta de LINQ a SQL (o lo que sea), necesitará un enfoque diferente. Si ya es LINQ a objetos, sin embargo:

return db.Exp.Where(rs => rs.ID == id) 
      .MaxBy(rs => rs.Amt) 
      .Received; 

Tenga en cuenta que esto está haciendo lo que las palabras de su pregunta preguntan:

  • Fuera de los registros con el identificador dado ...
  • encontrar el uno con la cantidad más alta ...
  • y comprobar el valor de Received

Ésta es no lo mismo que:

  • Fuera de los registros con el identificador dado, donde recibió es cierto ...
  • encontrar el uno con la cantidad más alta

También tenga en cuenta que esto arrojará una excepción si hay registros no con esa ID.

Si desea hacerlo en LINQ a SQL, etc., probablemente estaría mejor con un ordenamiento:

var highest = db.Exp.Where(rs => rs.ID == id) 
        .OrderByDescending(rs => rs.Amt) 
        .FirstOrDefault(); 
return highest != null && highest.Received; 

Usted No quiero hacer esto si está usando LINQ a Objetos, ya que ordenará todos los resultados, cuando solo desee encontrar el resultado con la cantidad más alta.

+0

Jon, ¿cómo harías lo anterior en C# linq? (desde rs en db ....) –

+0

@NatePet: ¿Quiere decir en una expresión de consulta? ¿Qué pedazo de código? Básicamente no hay soporte de expresión de consulta para 'FirstOrDefault()' (y obviamente no para 'MaxBy') por lo que tendría que poner corchetes alrededor de la expresión de consulta para llamar a los métodos al final, y su proyección sería un no -op. Básicamente sería más feo. Definitivamente * vale la pena sentirse cómodo con ambas formas. –

Cuestiones relacionadas