3

我有以下类结构:

 public class TaskLog
 {
    public DateTime LogDate { get; set; }
    public string Robot { get; set; }
    public string Task { get; set; }
    public Enums.ProbeDataState State { get; set; }

    public TaskLog()
    {
    }
}

我创建了一个通用列表,如下所示:

List<TaskLog> Logs;

我的输出:

Robot   Date                    State
---------------------------------------------
aaa     8/5/2013 12:00:00 AM    Task:1=fileDeltaFailed
aaa     8/5/2013 12:00:00 AM    Task:2=fileDeltaFailed
aaa     8/5/2013 12:00:00 AM    Task:4=fileDeltaFailed
bbb     8/5/2013 12:00:00 AM    Task:1=fileDeltaFailed
bbb     8/5/2013 12:00:00 AM    Task:2=fileDeltaFailed
bbb     8/5/2013 12:00:00 AM    Task:4=fileDeltaFailed

但是,我想将任务和状态分组如下:

                                Tasks
Robot   Date                    1                 2                4
aaa     8/5/2013 12:00:00 AM    fileDeltaFailed   fileDeltaFailed  fileDeltaFailed 
bbb     8/5/2013 12:00:00 AM    fileDeltaFailed   fileDeltaFailed  fileDeltaFailed

我尝试使用 groupby 没有运气,并且非常卡住。

例如

 var dataQuery = Logs.Where(w => w.LogDate >= start && w.LogDate <= finish).GroupBy(g => g.LogDate).Select(t => new
            {
                LogDate = t.Key,
                Details = t.OrderBy(o => o.Robot)
            }).ToList();
4

3 回答 3

5

如果我理解这个问题,您需要每个机器人的任务到状态的映射。您可以按机器人分组并为每个组选择一个字典:

Logs.GroupBy(t => t.Robot).Select(g => new {
    Robot = g.Key,
    TaskStates = g.ToDictionary(t => t.Task, t => t.State)
})

这假设每个机器人的任务名称都是唯一的(ToDictionary否则会抛出异常)。

您还可以为日期添加另一个级别的分组:

Logs.GroupBy(t => t.LogDate).Select(g => new {
    Date = g.Key,
    Details = g.GroupBy(t => t.Robot).Select(g => new {
        Robot = g.Key,
        TaskStates = g.ToDictionary(t => t.Task, t => t.State)
    }).ToList()
})

请注意,该Details属性本质上等同于我的第一个示例,唯一的区别是它查询外部分组而不是整个序列。结果是 {Date, Details} 的序列,其中每个“详细信息”是 {Robot, TaskStates} 的列表。

我还没有对此进行测试,所以如果我遗漏了任何错误,请告诉我。

于 2013-08-14T18:15:54.503 回答
1
var result = Logs.GroupBy(x=> new {x.Robot, x.Date})                     
                 .Select(g=> {
                               var a = g.ToList();
                               return
                               new {
                                 a[0].Robot,
                                 a[0].Date,
                                 Task1 = a[0].State,
                                 Task2 = a[1].State,
                                 Task4 = a[2].State
                               };
                             });

假设你必须定义一个固定的数量Tasks并使其更安全,我们可以这样做:

var result = Logs.GroupBy(x=> new {x.Robot, x.Date})
                 .Select(g=> { 
                               var c = g.Count();
                               var a = g.ToList();
                               return 
                               new {
                                    a[0].Robot,
                                    a[0].Date,
                                    Task1 = a[0].State,
                                    Task2 = c > 1 ? a[1].State : "",
                                    Task4 = c > 2 ? a[2].State : ""
                                   };
                             });
于 2013-08-14T19:21:35.067 回答
0

试试这个:

var newData = from w in Logs
              where w.LogDate >= start && w.LogDate <= finish
              group w by w.LogDate into g
              select new 
              {
                  LogDate = g.Key,
                  Details = g.ToList().OrderBy(o => o.Robot)
              };

该查询newData包含具有 LogDate 和 Details 的对象列表(由机器人排序的任务列表)。

于 2013-08-14T17:38:37.630 回答