Cómo usar LINQ para agrupar y ordenar por cierta columna

ACTUALIZADO: se agregó una nueva columna que combina las columnas Fecha y Hora, que son campos de cadena en la columna DateTimeCombined, que es un campo DateTime

Entonces, lo que debe hacer LINQ es agrupar por columna de nombre y obtener la fila para cada nombre que tenga la fecha + hora más temprana. Luego debería agregar el resto de la fila para el nombre.

DataTable init:

dataT = new DataTable();
dataT.Columns.Add("Date", typeof(string));
dataT.Columns.Add("Time", typeof(string));
dataT.Columns.Add("Day", typeof(string));
dataT.Columns.Add("Name", typeof(string));
dataT.Columns.Add("Place", typeof(string));
dataT.Columns.Add("DateTimeCombined", typeof(DateTime));
dataT.Columns.Add("NameMessage", typeof(string));

Así que aquí está la DataTable inicial (que se recupera por defecto):

Date        Time        Day     Name        Place       DateTimeCombined            NameMessage
6/29/2017   8:30AM      MON     John        Orlance     6/29/2017 8:30:00 AM
6/29/2017   8:40AM      MON     John        Orlance     6/29/2017 8:40:00 AM
6/29/2017   8:50AM      MON     John        Orlance     6/29/2017 8:50:00 AM        
6/29/2017   9:10AM      MON     John        Orlance     6/29/2017 9:10:00 AM
6/29/2017   9:20AM      MON     John        Orlance     6/29/2017 9:20:00 AM
6/29/2017   1:00PM      MON     John        Orlance     6/29/2017 1:00:00 PM
6/30/2017   8:30AM      TUE     John        Orlance     6/30/2017 8:30:00 AM
6/30/2017   8:40AM      TUE     John        Orlance     6/30/2017 8:40:00 AM
6/29/2017   8:15AM      MON     Mike        Atlanta     6/29/2017 8:15:00 AM
6/29/2017   8:30AM      MON     Mike        Atlanta     6/29/2017 8:30:00 AM
6/29/2017   8:40AM      MON     Mike        Atlanta     6/29/2017 8:40:00 AM
6/29/2017   9:10AM      MON     Mike        Atlanta     6/29/2017 9:10:00 AM
6/29/2017   9:20AM      MON     Mike        Atlanta     6/29/2017 9:20:00 AM
6/30/2017   8:30AM      TUE     Mike        Atlanta     6/30/2017 8:30:00 AM
6/30/2017   8:40AM      TUE     Mike        Atlanta     6/30/2017 8:40:00 AM
                                Christine   Marion                                  None
                                Steph       Kearney                                 None
6/29/2017   8:30AM      MON     Jenny       Boise       6/29/2017 8:30:00 AM
6/29/2017   8:40AM      MON     Jenny       Boise       6/29/2017 8:40:00 AM
6/29/2017   8:50AM      MON     Jenny       Boise       6/29/2017 8:50:00 AM
6/29/2017   9:10AM      MON     Jenny       Boise       6/29/2017 9:10:00 AM
6/29/2017   9:20AM      MON     Jenny       Boise       6/29/2017 9:20:00 AM
6/30/2017   8:30AM      TUE     Jenny       Boise       6/30/2017 8:30:00 AM
6/30/2017   8:40AM      TUE     Jenny       Boise       6/30/2017 8:40:00 AM
6/29/2017   8:30AM      MON     Kelly       Ardsley     6/29/2017 8:30:00 AM
6/29/2017   8:40AM      MON     Kelly       Ardsley     6/29/2017 8:40:00 AM
6/29/2017   8:50AM      MON     Kelly       Ardsley     6/29/2017 8:50:00 AM
6/29/2017   9:10AM      MON     Kelly       Ardsley     6/29/2017 9:10:00 AM
6/29/2017   9:20AM      MON     Kelly       Ardsley     6/29/2017 9:20:00 AM
6/30/2017   8:30AM      TUE     Kelly       Ardsley     6/30/2017 8:30:00 AM
6/30/2017   8:40AM      TUE     Kelly       Ardsley     6/30/2017 8:40:00 AM
                                Joseph      Houston                                 None

La primera función de LINQ debería ser obtener la anteriorDateTimeCombined para cada nombre:

6/29/2017   8:30AM      MON     John        Orlance     6/29/2017 8:30:00 AM
6/29/2017   8:15AM      MON     Mike        Atlanta     6/29/2017 8:15:00 AM
6/29/2017   8:30AM      MON     Jenny       Boise       6/29/2017 8:30:00 AM
6/29/2017   8:30AM      MON     Kelly       Ardsley     6/29/2017 8:30:00 AM

La siguiente función debería ser ordenar eso porDateTimeCombined:

- If `DateTimeCombined` is same, order first by `DateTimeCombined` and then by Name.

- If `DateTimeCombined` is same AND Name is same, order first by `DateTimeCombined` and then by Name and then by Place.


6/29/2017   8:15AM      MON     Mike        Atlanta     6/29/2017 8:15:00 AM
6/29/2017   8:30AM      MON     Jenny       Boise       6/29/2017 8:30:00 AM
6/29/2017   8:30AM      MON     John        Orlance     6/29/2017 8:30:00 AM
6/29/2017   8:30AM      MON     Kelly       Ardsley     6/29/2017 8:30:00 AM

La siguiente función debería ser poner el resto de las filas para cada nombre (la DataTable final debería tener este aspecto):

6/29/2017   8:15AM      MON     Mike        Atlanta     6/29/2017 8:15:00 AM
6/29/2017   8:30AM      MON     Mike        Atlanta     6/29/2017 8:30:00 AM
6/29/2017   8:40AM      MON     Mike        Atlanta     6/29/2017 8:40:00 AM
6/29/2017   9:10AM      MON     Mike        Atlanta     6/29/2017 9:10:00 AM
6/29/2017   9:20AM      MON     Mike        Atlanta     6/29/2017 9:20:00 AM
6/30/2017   8:30AM      TUE     Mike        Atlanta     6/30/2017 8:30:00 AM
6/30/2017   8:40AM      TUE     Mike        Atlanta     6/30/2017 8:40:00 AM
6/29/2017   8:30AM      MON     Jenny       Boise       6/29/2017 8:30:00 AM
6/29/2017   8:40AM      MON     Jenny       Boise       6/29/2017 8:40:00 AM
6/29/2017   8:50AM      MON     Jenny       Boise       6/29/2017 8:50:00 AM
6/29/2017   9:10AM      MON     Jenny       Boise       6/29/2017 9:10:00 AM
6/29/2017   9:20AM      MON     Jenny       Boise       6/29/2017 9:20:00 AM
6/30/2017   8:30AM      TUE     Jenny       Boise       6/30/2017 8:30:00 AM
6/30/2017   8:40AM      TUE     Jenny       Boise       6/30/2017 8:40:00 AM
6/29/2017   8:30AM      MON     John        Orlance     6/29/2017 8:30:00 AM
6/29/2017   8:40AM      MON     John        Orlance     6/29/2017 8:40:00 AM
6/29/2017   8:50AM      MON     John        Orlance     6/29/2017 8:50:00 AM        
6/29/2017   9:10AM      MON     John        Orlance     6/29/2017 9:10:00 AM
6/29/2017   9:20AM      MON     John        Orlance     6/29/2017 9:20:00 AM
6/29/2017   1:00PM      MON     John        Orlance     6/29/2017 1:00:00 PM
6/30/2017   8:30AM      TUE     John        Orlance     6/30/2017 8:30:00 AM
6/30/2017   8:40AM      TUE     John        Orlance     6/30/2017 8:40:00 AM
6/29/2017   8:30AM      MON     Kelly       Ardsley     6/29/2017 8:30:00 AM
6/29/2017   8:40AM      MON     Kelly       Ardsley     6/29/2017 8:40:00 AM
6/29/2017   8:50AM      MON     Kelly       Ardsley     6/29/2017 8:50:00 AM
6/29/2017   9:10AM      MON     Kelly       Ardsley     6/29/2017 9:10:00 AM
6/29/2017   9:20AM      MON     Kelly       Ardsley     6/29/2017 9:20:00 AM
6/30/2017   8:30AM      TUE     Kelly       Ardsley     6/30/2017 8:30:00 AM
6/30/2017   8:40AM      TUE     Kelly       Ardsley     6/30/2017 8:40:00 AM

Nota: Si Kelly era John (John apareciendo dos veces), por ejemplo, entonces el grupo Ardsley iría antes que Orlance.

Lo que probé hasta ahora:

var ordered = dataTable.AsEnumerable().OrderBy(en => en.Field<DateTime>("DateTimeCombined")).CopyToDataTable();

Actualizar:

var ordered = dataTable.AsEnumerable()
                .OrderBy(en => en.Field<DateTime>("DateTimeCombined"))
            .GroupBy(en1 => en1.Field<string>("Name")).ToList();

Solo me da el nombre solamente.

Actualizar:

  var q = dataTable.AsEnumerable()
                .GroupBy(item => item.Field<string>("Name"))
                .SelectMany(grouping => grouping.Take(1))
                .OrderBy(item => item.Field<DateTime>("CombinedDateTime"))
                .ThenBy(item => item.Field<string>("Name"))
                .ThenBy(item => item.Field<string>("Place"))
                .CopyToDataTable();

Lo anterior funciona como se esperaba:

6/29/2017   8:15AM      MON     Mike        Atlanta     6/29/2017 8:15:00 AM
6/29/2017   8:30AM      MON     Jenny       Boise       6/29/2017 8:30:00 AM
6/29/2017   8:30AM      MON     John        Orlance     6/29/2017 8:30:00 AM
6/29/2017   8:30AM      MON     Kelly       Ardsley     6/29/2017 8:30:00 AM

pero solo si tomo la primera fila de cada grupo (por nombre). Si tomo todo por grupo, las filas se mezclan. ¿Cómo puedo ahora, agregar el resto deMike's filas después de la fila de Mike, agregue el resto deJenny's filas después de la fila de Jenny, y así sucesivamente? ¿Se puede hacer esto en el mismo LINQ?

Respuestas a la pregunta(1)

Su respuesta a la pregunta