Supongamos que tengo una clase que representa las líneas de órdenes, por ejemplo¿Cómo aplana una consulta de Linq después de usar la agrupación doble?
public class Line
{
public string Code ;
public string No ; // Invoice Number
public DateTime Date ;
public string Product ;
public decimal Quantity ;
}
y una lista de líneas, por ejemplo
List<Line> myList = new List<Line>();
myList.Add(new Line() { Code = "ABC001", No = "1001" ,Date = new DateTime(2012,4,1) , Product = "X", Quantity= 1m});
myList.Add(new Line() { Code = "ABC001", No = "1001" ,Date = new DateTime(2012,4,1) , Product = "Y", Quantity= 1m});
myList.Add(new Line() { Code = "ABC002", No = "1002" ,Date = new DateTime(2012,4,2) , Product = "X", Quantity= 1m});
myList.Add(new Line() { Code = "ABC002", No = "1002" ,Date = new DateTime(2012,4,2) , Product = "Y", Quantity= 1m});
myList.Add(new Line() { Code = "ABC002", No = "1003" ,Date = new DateTime(2012,4,3) , Product = "Z", Quantity= 1m});
myList.Add(new Line() { Code = "ABC002", No = "1004" ,Date = new DateTime(2012,4,4) , Product = "X", Quantity= 1m});
myList.Add(new Line() { Code = "ABC003", No = "1005" ,Date = new DateTime(2012,4,4) , Product = "X", Quantity= 1m});
myList.Add(new Line() { Code = "ABC003", No = "1006" ,Date = new DateTime(2012,4,4) , Product = "X", Quantity= 1m});
myList.Add(new Line() { Code = "ABC003", No = "1006" ,Date = new DateTime(2012,4,4) , Product = "Y", Quantity= 1m});
Busco para recuperar todas las líneas en las que el código de cliente tiene más de una factura. Para hacer esto, estoy ante todo agrupando por Código, No y Fecha y luego agrupando eso por Código de cliente y para cualquier cliente que tenga dos o más registros, estoy seleccionando todos menos el primer registro.
así:
var query1 =
(from r in myList
group r by new { r.Code , r.No , r.Date } into results
group results by new { results.Key.Code } into results2
where results2.Count() > 1
select new
{
results2.Key.Code ,
Count = results2.Count(),
Results = results2.OrderBy(i=>i.Key.Date).Skip(1).ToList()
// Skip the first invoice
}
).ToList();
consulta1 ahora contiene los registros correctos, pero envuelto en el interior IGrouping y estoy teniendo problemas obtiene los resultados como una List<Line>
me trataron query1.SelectMany (r = > r.Results) .ToList();
pero esto todavía me deja con IGrouping y ahí es donde estoy atascado.
que podría recurrir a la bucles for anidados como en
List<Line> output = new List<Line>();
foreach (var r1 in query1)
{
foreach(var r2 in r1.Results)
foreach(var r3 in r2)
output.Add(r3);
}
pero hay una manera mejor/LINQ?
La salida real debería ser de cuatro líneas como en
// Code No Date Product Quantity
// ABC002 1003 03/04/2012 00:00:00 Z 1
// ABC002 1004 04/04/2012 00:00:00 X 1
// ABC003 1006 04/04/2012 00:00:00 X 1
// ABC003 1006 04/04/2012 00:00:00 Y 1
que cambiaría 'results2.ToList() OrdenarPor (i => i.Key.Date) Saltee (1) .ToList() 'to' results2.OrderBy (i => i.Key.Date) .Skip (1) .ToList() '. No hay ninguna razón para la primera llamada 'ToList()'. – phoog
@phoog He eliminado el primer ToList() ya que tiene razón en que no es necesario, pero tampoco afecta los resultados, así que todavía tengo mi problema original. – sgmoore
sí, publiqué eso como un comentario porque no responde su pregunta. También publiqué una respuesta a continuación. – phoog