Cuando se utiliza grupo por LINQ crea una nueva colección de artículos por lo que tiene dos colecciones de artículos.
he aquí una solución a ambos problemas:
- sumando cualquier cantidad de miembros en una iteración y
- evitar la duplicación de la colección de su elemento
Código:
public static class LinqExtensions
{
/// <summary>
/// Computes the sum of the sequence of System.Double values that are obtained
/// by invoking one or more transform functions on each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a sum.</param>
/// <param name="selectors">The transform functions to apply to each element.</param>
public static double[] SumMany<TSource>(this IEnumerable<TSource> source, params Func<TSource, double>[] selectors)
{
if (selectors.Length == 0)
{
return null;
}
else
{
double[] result = new double[selectors.Length];
foreach (var item in source)
{
for (int i = 0; i < selectors.Length; i++)
{
result[i] += selectors[i](item);
}
}
return result;
}
}
/// <summary>
/// Computes the sum of the sequence of System.Decimal values that are obtained
/// by invoking one or more transform functions on each element of the input sequence.
/// </summary>
/// <param name="source">A sequence of values that are used to calculate a sum.</param>
/// <param name="selectors">The transform functions to apply to each element.</param>
public static double?[] SumMany<TSource>(this IEnumerable<TSource> source, params Func<TSource, double?>[] selectors)
{
if (selectors.Length == 0)
{
return null;
}
else
{
double?[] result = new double?[selectors.Length];
for (int i = 0; i < selectors.Length; i++)
{
result[i] = 0;
}
foreach (var item in source)
{
for (int i = 0; i < selectors.Length; i++)
{
double? value = selectors[i](item);
if (value != null)
{
result[i] += value;
}
}
}
return result;
}
}
}
Aquí está la forma en que tiene que hacer la sumatoria:
double[] result = m.Items.SumMany(p => p.Total, q => q.Done);
Aquí está un ejemplo general:
struct MyStruct
{
public double x;
public double y;
}
MyStruct[] ms = new MyStruct[2];
ms[0] = new MyStruct() { x = 3, y = 5 };
ms[1] = new MyStruct() { x = 4, y = 6 };
// sum both x and y members in one iteration without duplicating the array "ms" by GROUPing it
double[] result = ms.SumMany(a => a.x, b => b.y);
como se puede ver
result[0] = 7
result[1] = 11
O cuando artículo no tiene identificador único, se podría escribir 'grupo p por p en g'. – Steven
Eso hizo el truco, aunque con una modificación: de p en m.Items grupo p por p.Id en g seleccione nuevo {SumTotal = g.Sum (r => r.Total), SumDone = g.Sum (r => r.Done)} – Axarydax
Tiene razón, 'p' ya se utilizó en la consulta. Arreglado. – Steven