LINQ to SQL y un total acumulado de resultados ordenados

Quiero mostrar el historial contable de un cliente en DataGridView y quiero tener una columna que muestre el total acumulado de su saldo. La antigua forma en que lo hice fue obtener los datos, recorrer los datos y agregar filas al DataGridView uno a uno y calcular el total acumulado en ese momento. Cojo. Prefiero usar LINQ to SQL, o LINQ si no es posible con LINQ to SQL, para calcular los totales acumulados, así puedo simplemente establecer DataGridView.DataSource en mis datos.

Este es un ejemplo súper simplificado de lo que estoy buscando. Digamos que tengo la siguiente clase.

 class Item { public DateTime Date { get; set; } public decimal Amount { get; set; } public decimal RunningTotal { get; set; } } 

Me gustaría una statement L2S o LINQ que pueda generar resultados que se vean así:

  Date Amount RunningTotal 12-01-2009 5 5 12-02-2009 -5 0 12-02-2009 10 10 12-03-2009 5 15 12-04-2009 -15 0 

Tenga en cuenta que puede haber varios elementos con la misma fecha (12-02-2009). Los resultados deben ordenarse por fecha antes de calcular los totales acumulados. Supongo que esto significa que necesitaré dos declaraciones, una para obtener los datos y ordenarlos, y otra para realizar el cálculo del total acumulado.

Esperaba que Aggregate hiciera el truco, pero no funciona como esperaba. O tal vez simplemente no pude resolverlo.

Esta pregunta parecía ir después de lo mismo que quería, pero no veo cómo la respuesta aceptada / única resuelve mi problema.

¿Alguna idea sobre cómo llevarlo a cabo?

Editar Combinando las respuestas de Alex y DOK, esto es con lo que terminé:

 decimal runningTotal = 0; var results = FetchDataFromDatabase() .OrderBy(item => item.Date) .Select(item => new Item { Amount = item.Amount, Date = item.Date, RunningTotal = runningTotal += item.Amount }); 

Uso de cierres y método anónimo:

 List myList = FetchDataFromDatabase(); decimal currentTotal = 0; var query = myList .OrderBy(i => i.Date) .Select(i => { currentTotal += i.Amount; return new { Date = i.Date, Amount = i.Amount, RunningTotal = currentTotal }; } ); foreach (var item in query) { //do with item } 

Qué tal esto: (el crédito va a esta fuente )

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { delegate string CreateGroupingDelegate(int i); static void Main(string[] args) { List list = new List() { 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 69, 2007}; int running_total = 0; var result_set = from x in list select new { num = x, running_total = (running_total = running_total + x) }; foreach (var v in result_set) { Console.WriteLine( "list element: {0}, total so far: {1}", v.num, v.running_total); } Console.ReadLine(); } } } 

En caso de que aún no se haya respondido, tengo una solución que he estado usando en mis proyectos. Esto es bastante similar a un grupo con particiones Oracle. La clave es hacer que la cláusula where en el total acumulado coincida con la lista orig y luego agruparla por fecha.

 var itemList = GetItemsFromDBYadaYadaYada(); var withRuningTotals = from i in itemList select i.Date, i.Amount, Runningtotal = itemList.Where( x=> x.Date == i.Date). GroupBy(x=> x.Date). Select(DateGroup=> DateGroup.Sum(x=> x.Amount)).Single(); 

El agregado se puede usar para obtener un total acumulado también:

 var src = new [] { 1, 4, 3, 2 }; var running = src.Aggregate(new List(), (a, i) => { a.Add(a.Count == 0 ? i : a.Last() + i); return a; }); 
 using System; using System.Linq; using System.Collections.Generic; public class Program { public static void Main() { var list = new List{1, 5, 4, 6, 8, 11, 3, 12}; int running_total = 0; list.ForEach(x=> Console.WriteLine(running_total = x+running_total)); } }