LINQ过滤器第N级嵌套列表

时间:2017-06-28 10:24:42

标签: c# linq linq-to-sql

我的项目中有以下层次结构:

  1. 活动
  2. 任务
  3. 步骤
  4. 响应
  5. 这意味着一项活动有许多任务,而这些任务又有很多步骤,一步就有很多反应。

    以下是我的POCO课程:

    public class Activity
    {
        public virtual ICollection<Task> Tasks { get; set; }
    }
    
    public class Task
    {
        public virtual ICollection<Step> Steps{ get; set; }
    }
    
    
    public class Step
    {
        public virtual int DisplayOrder { get; set; }
        public virtual ICollection<Response> Responses{ get; set; }
    }
    
    public class Response
    {
        public virtual int UserId { get; set; }
    
        public virtual int ResponseText{ get; set; }
    }
    

    现在,我需要返回按List<Activity>排序的ActivityId,并按DisplayOrder排序步骤,并且还有仅属于给定UserId的响应。

    以下是我的尝试:

    Activities.ToList()
                    .ForEach((activity) => activity.Tasks.ToList()
                    .ForEach((task) => task.Steps = task.Steps.OrderBy(s => s.DisplayOrder).ToList()
                    .ForEach((step) =>  step.Responses = step.Responses.Where(r => r.UserId == RequestorUserId)))
                    ));
    

    这给了我一个错误:

      

    无法将类型'void'隐式转换为ICollection<Step>

1 个答案:

答案 0 :(得分:0)

ForEach扩展方法不会返回任何内容,而您尝试将结果设置为task.Steps。通过使用Select方法更改行

中的对象,可以获得所需的结果
    Activities.ToList()
            .ForEach((activity) => activity.Tasks.ToList()
            .ForEach((task) => task.Steps = task.Steps.OrderBy(s => s.DisplayOrder).ToList()
            .Select((step) =>  
                {
                    step.Responses = step.Responses.Where(r => r.UserId == 1).ToList();
                    return step;
                }).ToList()));

另外,如果可能的话,可能需要将类型更改为IEnumerable而不是ICollection,因为您不需要所有的ToList()调用。

如果您需要分配结果,那么您还需要替换第一个ForEach - 尝试类似:

var a = Activities.ToList()
            .Select((activity) =>
                {
                    activity.Tasks.ToList()
                        .ForEach((task) => task.Steps = task.Steps.OrderBy(s => s.DisplayOrder).ToList()
                        .Select((step) =>
                            {
                                step.Responses = step.Responses.Where(r => r.UserId == 1).ToList();
                                return step;
                            }).ToList());
                    return activity;
                });