简体   繁体   中英

LINQ group by select with collection

I have a datatable eg

ID  Agent  Date
1   A1    2016-02-19
2   A1    2016-02-20
3   A2    2016-02-19
4   A3    2016-02-20

i want to group these records by Date and return the ID and Agent is list like:

Date:2016-02-19 ,{(1,A1),(3,A2)}
Date:2016-02-20 ,{(2,A1),(4,A3)}

A collection object of ID and Agent Group by Date. Please suggect how to achieve it using LINQ.

I think that something like the below would do that you want.

var result = datatable.AsEnumerable()
                      .GroupBy(row=>row.Field<DateTime>("Date"))
                      .Select(gr=>new 
                      {
                          Date = gr.Key,
                          Agents = gr.Select(x => new 
                          {
                              Id = x.Field<int>("ID"),
                              Agent = x.Field<string>("Agent")
                          })
                      });

Update

If you need for each date the agents to be a comma separated list of the agents, like this {(2,A1),(4,A3)} , you could try the following approach.

var result = datatable.AsEnumerable()
                          .GroupBy(row=>row.Field<DateTime>("Date"))
                          .Select(gr=>new 
                          {
                              Date = gr.Key,
                              Agents = "{"+ string.Join(",", 
                                       gr.Select(x => new 
                              string.Format("({0},{1})", 
                                  x.Field<int>("ID"), 
                                  x.Field<string>("Agent"))+"}"
                              })
                          });

Here is my example class:

public class Log
{
    public int ID { get; set; }
    public string Agent { get; set; }
    public DateTime Date { get; set; }

    public Log(int id, string agent, DateTime date)
    {
        ID = id;
        Agent = agent;
        Date = date;
    }
}

And here the LINQ statement with some test data:

List<Log> list = new List<Log>()
{
    new Log(1, "A", new DateTime(2016, 01, 01, 0, 0, 0)),
    new Log(2, "B", new DateTime(2016, 01, 01, 0, 0, 0)),
    new Log(3, "C", new DateTime(2016, 01, 01, 0, 0, 0)),
    new Log(4, "A", new DateTime(2016, 01, 02, 0, 0, 0)),
    new Log(5, "A", new DateTime(2016, 01, 03, 0, 0, 0))
};

var result = from entry in list
             group entry by entry.Date
             into g
             select g;

This will group all your data into groups with a Key based on Log.Date , where each group consits of multiple entries, each with an ID , Agent and Date property.

Here some example code how to access result :

result.ToList().ForEach(group =>
{
    Console.WriteLine(group.Key); // The date
    group.ToList().ForEach(entry => Console.WriteLine(entry.ID + " - " + entry.Agent)); // Print out each entry per group
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM