使用Linq过滤深层json层次结构

时间:2020-04-01 14:56:29

标签: linq

鉴于下面的json,我想将其投影为WorkflowStepName="Translate"Status="FINISHED"的新类型。

我的尝试无效

var y = statuses.Where(s => s.Jobs.Any(j => j.Steps.Any(js => js.WorkflowStepName.Equals("Translate") && js.Status.Equals("ACTIVE"))))
        .SelectMany(s => s.Jobs.Select(j => new JJob()
            { ProjectId = s.ProjectId, JobId = j.JobId, Name = j.FileName, TargetLanguage = j.TargetLanguage}));
[
    {
        "Activity": "ARCHIVED",
        "CompletionStatus": "FINISHED",
        "Jobs": [
            {
                "CompletionStatus": "FINISHED",
                "FileName": "j1.xlf",
                "JobId": 1,
                "Steps": [
                    {
                        "AutoStatus": null,
                        "Status": "FINISHED",
                        "WorkflowStepName": "Review"
                    }
                ],
                "TargetLanguage": "ar_EG"
            }
        ],
        "ProjectId": 11,
        "SourceLanguage": "en_US"
    },
    {
        "Activity": "ACTIVE",
        "CompletionStatus": "FINISHED",
        "Jobs": [
            {
                "CompletionStatus": "FINISHED",
                "FileName": "j2.xlf",
                "JobId": 2,
                "Steps": [
                    {
                        "AutoStatus": null,
                        "Status": "FINISHED",
                        "WorkflowStepName": "Translate"
                    }
                ],
                "TargetLanguage": "zh_TW"
            }
        ],
        "ProjectId": 22,
        "SourceLanguage": "en_US"
    },
    {
        "Activity": "ACTIVE",
        "CompletionStatus": "IN_PROGRESS",
        "Jobs": [
            {
                "CompletionStatus": "FINISHED",
                "FileName": "j3.xlf",
                "JobId": 3,
                "Steps": [
                    {
                        "AutoStatus": null,
                        "Status": "FINISHED",
                        "WorkflowStepName": "Translate"
                    }
                ],
                "TargetLanguage": "de_DE"
            }
        ],
        "ProjectId": 33,
        "SourceLanguage": "en_US"
    }
]

我可以编写一个静态扩展,该扩展使用嵌套的foreach循环来实现正确的目标,但似乎Linq应该有一种方法。还尝试了各种子选择,但是我需要从层次结构顶部开始将扁平化的数据(例如ProjectIdJobId)用于

1 个答案:

答案 0 :(得分:0)

您可以尝试通过这种SelectMany()重载来访问父级层次结构引用:

var y = statuses.SelectMany(s => s.Jobs.SelectMany(j => j.Steps, (job, step) => new {Job = job, Step = step}), (project, jobStep) => new {Project = project, JobStep = jobStep})
                .Where(js => js.JobStep.Step.WorkflowStepName.Equals("Translate") && js.JobStep.Step.Status.Equals("FINISHED"))
                .Select(j => new JJob { ProjectId = j.Project.ProjectId, JobId = j.JobStep.Job.JobId, Name = j.JobStep.Job.FileName, TargetLanguage = j.JobStep.Job.TargetLanguage});

基本上将您的层次结构简化为Tuple<Project, Tuple<Job, Step>>的平坦列表(我使用匿名对象,但思路保持不变),然后您可以根据需要查询和投影。

相关问题