使用带连接的 linq 查询查询嵌套对象
Querying nested objects using linq query with join
我从 api 获得以下 json 结构:
{
"event_instance": [
{
"id": 55551244,
"event_id": 11112,
"name": "Brown Belt Karate Class",
"staff_members": [
{
"id": 12345,
"name": "John Smith"
}
],
"people": [
{
"id": 111,
"name": "Jane Doe"
},
{
"id": 222,
"name": "Josh Smith"
},
{
"id": 333,
"name": "Ben Johnson"
}
],
"visits": [
{
"id": 1234578,
"person_id": 111,
"state": "completed",
"status": "complete"
},
{
"id": 1239865,
"person_id": 222,
"state": "completed",
"status": "complete"
},
{
"id": 1239865,
"person_id": 333,
"state": "canceled",
"status": "cancel"
}
]
}
]
}
我正在使用 JSON.NET 将其反序列化为以下 .net 对象:
[JsonObjectAttribute("event_instance")]
public class EventInstance
{
[JsonPropertyAttribute("id")]
public int Id { get; set; }
[JsonPropertyAttribute("event_id")]
public int EventId { get; set; }
[JsonPropertyAttribute("name")]
public string Name { get; set; }
[JsonPropertyAttribute("staff_members")]
public List<StaffMember> StaffMembers { get; set; }
[JsonPropertyAttribute("visits")]
public List<Visit> Visits { get; set; }
[JsonPropertyAttribute("people")]
public List<Student> Students { get; set; }
}
[JsonObjectAttribute("staff_members")]
public class StaffMember
{
[JsonPropertyAttribute("id")]
public int Id { get; set; }
[JsonPropertyAttribute("name")]
public string Name { get; set; }
}
[JsonObjectAttribute("people")]
public class People
{
[JsonPropertyAttribute("id")]
public int Id { get; set; }
[JsonPropertyAttribute("name")]
public string Name { get; set; }
}
[JsonObjectAttribute("visits")]
public class Visits
{
[JsonPropertyAttribute("id")]
public int Id { get; set; }
[JsonPropertyAttribute("person_id")]
public int PersonId { get; set; }
[JsonPropertyAttribute("state")]
public string State { get; set; }
[JsonPropertyAttribute("status")]
public string Status { get; set; }
}
我正在使用以下代码反序列化:
var event = (EventInstance)JsonConvert.DeserializeObject(json, typeof(EventInstance));
以上工作正常,并为我提供了上述 json 结构的准确对象表示。现在我正在尝试将此事件对象查询到 filter/project 到一个新结构,然后我可以将该结构序列化回 json 并向下发送到浏览器。我需要 return 状态为 "completed" 且状态为 "complete" 的学生列表。如您所见,people 数组与 visits 数组相关联(具有 id 和 person_id)。我想生成以下简单输出:
- 11112,棕带空手道 Class,John Smith,111,Jane Doe
- 11112,空手道棕带 Class,约翰·史密斯,222,约什·史密斯
我试过这样的事情:
var studentList = from theClass in event
from staff in theClass.StaffMembers
from student in theClass.People
from visits in theClass.Visits
where visits.Status == "complete"
&& visits.State == "completed"
select new
{
event_id = theClass.EventId
class_name = theClass.Name,
instructor_name = staff.Name,
student_id = student.Id,
student_name = student.Name
};
string _data = JsonConvert.SerializeObject(studentList);
这自然会产生重复的学生姓名。我是 linq 的新手。基本上我需要 join/tie people 和 visits 数组,所以我只取回该 ID 的单个学生,以及该事件的根数据。也非常感谢任何关于更好的方法的建议!
诀窍是将学生和访问加入到一个集合中,该集合包含以下两者的数据:
from ei in eventInstances
from sm in ei.StaffMembers
from x in
(from vi in ei.Visits
join st in ei.Students on vi.PersonId equals st.Id
select new { vi, st }) // Here you get students and visits side-by-side
select new
{
ei.EventId,
Event = ei.Name,
StaffMemeber = sm.Name,
PersonId = x.st.Id,
Student = x.st.Name
}
我从 api 获得以下 json 结构:
{
"event_instance": [
{
"id": 55551244,
"event_id": 11112,
"name": "Brown Belt Karate Class",
"staff_members": [
{
"id": 12345,
"name": "John Smith"
}
],
"people": [
{
"id": 111,
"name": "Jane Doe"
},
{
"id": 222,
"name": "Josh Smith"
},
{
"id": 333,
"name": "Ben Johnson"
}
],
"visits": [
{
"id": 1234578,
"person_id": 111,
"state": "completed",
"status": "complete"
},
{
"id": 1239865,
"person_id": 222,
"state": "completed",
"status": "complete"
},
{
"id": 1239865,
"person_id": 333,
"state": "canceled",
"status": "cancel"
}
]
}
]
}
我正在使用 JSON.NET 将其反序列化为以下 .net 对象:
[JsonObjectAttribute("event_instance")]
public class EventInstance
{
[JsonPropertyAttribute("id")]
public int Id { get; set; }
[JsonPropertyAttribute("event_id")]
public int EventId { get; set; }
[JsonPropertyAttribute("name")]
public string Name { get; set; }
[JsonPropertyAttribute("staff_members")]
public List<StaffMember> StaffMembers { get; set; }
[JsonPropertyAttribute("visits")]
public List<Visit> Visits { get; set; }
[JsonPropertyAttribute("people")]
public List<Student> Students { get; set; }
}
[JsonObjectAttribute("staff_members")]
public class StaffMember
{
[JsonPropertyAttribute("id")]
public int Id { get; set; }
[JsonPropertyAttribute("name")]
public string Name { get; set; }
}
[JsonObjectAttribute("people")]
public class People
{
[JsonPropertyAttribute("id")]
public int Id { get; set; }
[JsonPropertyAttribute("name")]
public string Name { get; set; }
}
[JsonObjectAttribute("visits")]
public class Visits
{
[JsonPropertyAttribute("id")]
public int Id { get; set; }
[JsonPropertyAttribute("person_id")]
public int PersonId { get; set; }
[JsonPropertyAttribute("state")]
public string State { get; set; }
[JsonPropertyAttribute("status")]
public string Status { get; set; }
}
我正在使用以下代码反序列化:
var event = (EventInstance)JsonConvert.DeserializeObject(json, typeof(EventInstance));
以上工作正常,并为我提供了上述 json 结构的准确对象表示。现在我正在尝试将此事件对象查询到 filter/project 到一个新结构,然后我可以将该结构序列化回 json 并向下发送到浏览器。我需要 return 状态为 "completed" 且状态为 "complete" 的学生列表。如您所见,people 数组与 visits 数组相关联(具有 id 和 person_id)。我想生成以下简单输出:
- 11112,棕带空手道 Class,John Smith,111,Jane Doe
- 11112,空手道棕带 Class,约翰·史密斯,222,约什·史密斯
我试过这样的事情:
var studentList = from theClass in event
from staff in theClass.StaffMembers
from student in theClass.People
from visits in theClass.Visits
where visits.Status == "complete"
&& visits.State == "completed"
select new
{
event_id = theClass.EventId
class_name = theClass.Name,
instructor_name = staff.Name,
student_id = student.Id,
student_name = student.Name
};
string _data = JsonConvert.SerializeObject(studentList);
这自然会产生重复的学生姓名。我是 linq 的新手。基本上我需要 join/tie people 和 visits 数组,所以我只取回该 ID 的单个学生,以及该事件的根数据。也非常感谢任何关于更好的方法的建议!
诀窍是将学生和访问加入到一个集合中,该集合包含以下两者的数据:
from ei in eventInstances
from sm in ei.StaffMembers
from x in
(from vi in ei.Visits
join st in ei.Students on vi.PersonId equals st.Id
select new { vi, st }) // Here you get students and visits side-by-side
select new
{
ei.EventId,
Event = ei.Name,
StaffMemeber = sm.Name,
PersonId = x.st.Id,
Student = x.st.Name
}