2010-07-04 15 views
6

En una lista de objetos de transacción, estoy intentando agrupar por BatchNo y luego sumar las cantidades.C# LINQ to Objects: Group By/Sum help

public class Extract 
{ 
    // Notable fields in TRANSACTION are: String mBatchNo, String mAmount 
    private List<Transaction> Transactions; 

    public void testTransactions() 
    { 

     // Sum of amounts grouped by batch number 
     var sGroup = from t in Transactions 
        group t by t.mBatchNo into g 
        select new { batchNo = g.Key, 
            totalAmount = g.Max(a => (Int32.Parse(a.mAmount)))}; 
    } 
} 

En este punto, entro en el aspecto de código a través de la ventana locales para ver lo que mi conjunto de resultados es comprobar con el archivo He importado a este objeto.

El último lote en el archivo tiene 3 registros, 100 cantidad cada uno que se puede ver en el objeto de la lista de transacciones. Sin embargo, si se profundiza en el resultado del sGroup, se encuentra que el mismo lote tiene un total de 100 (debe ser 300). ¿Qué he metido en esta consulta?

Tenga en cuenta que he almacenado esto como una cadena ya que estamos llenos a cero a la izquierda de un campo de 8 caracteres. Por razones de exportación, decidí almacenar como una cadena. Aunque esto puede (y probablemente será) cambiado, no responde mi pregunta: ¿Cómo hacer que esta consulta agregue la suma en conjuntos por BatchNo?

Respuesta

16

es necesario llamar a Sum en lugar de Max:

var sGroup = from t in Transactions 
    group t by t.mBatchNo into g 
    select new { 
     batchNo = g.Key, 
     totalAmount = g.Sum(a => (int.Parse(a.mAmount))) // Sum, not Max 
    }; 

También sugeriría, si el campo mAmount se almacena como un string, de usar un método más robusto que int.Parse (ya que se producirá una excepción si la cadena no es un entero válido, por ejemplo, si está en blanco). Algo como esto:

int ParseOrZero(string text) 
{ 
    int value; 
    if (int.TryParse(text, out value)) 
     return value; 
    else 
     return 0; 
} 

var sGroup = from t in Transactions 
    group t by t.mBatchNo into g 
    select new { 
     batchNo = g.Key, 
     totalAmount = g.Sum(ParseOrZero) // blanks will be treated as 0 
    }; 
+0

wow ha sido un gran fin de semana para mí haberme perdido eso! ¡Gracias por la entrada de excepción también! – Mohgeroth

2

En lugar de hacer max debe usar sum en su grupo. En este momento, solo está configurando la propiedad al valor máximo en el objeto, sum sumará todos los valores en la propiedad.