Циклические ссылки при сериализации - C#
Формулировка задачи:
Есть три объекта: "Школа", "Учитель", "Ученик". "Школа" знает всех своих учителей и учеников, "Учитель" знает где работает и всех своих учеников, "Школьник" знает где учится, и своего учителя. Короче, мешанина циклических ссылок, но все отлично работает. Но только до тех пор, пока не придется сериализовать экземпляр класса "Школа". XmlSerializer валится с ошибкой "При сериализации объекта типа ... обнаружена циклическая ссылка.", DataContractJsonSerializer просто игнорирует такие объекты. BinaryFormatter справляется каким-то образом, но очень долго, и на выходе слишком "тяжелый" файл.
Как избавиться от циклических ссылок, сохранив при этом связи между объектами? На первый взгляд логично в дочерних объектах хранить только какие-то id-шники, но как по этому id получить экземпляр нужного класса?
Решение задачи: «Циклические ссылки при сериализации»
textual
Листинг программы
public class School
{
public int id;
public List<int> studentIds;
[XmlIgnore]
public List<Student> students;
public List<int> teacherIds;
[XmlIgnore]
public List<Teacher> teachers;
}
public class Teacher
{
public int id;
public List<int> studentIds;
[XmlIgnore]
public List<Student> students;
public int schoolId;
[XmlIgnore]
public School school;
}
public class Student
{
public int id;
public int teacherId;
[XmlIgnore]
public Teacher Teacher;
public int schoolId;
[XmlIgnore]
public School school;
}
public class SchoolDataBase
{
public List<School> schools;
public List<Teacher> teachers;
public List<Student> students;
public void SetData()
{
var schoolsDic = schools.ToDictionary(s => s.id, s => s);
var teachersDic = teachers.ToDictionary(s => s.id, s => s);
var studentsDic = students.ToDictionary(s => s.id, s => s);
foreach (var school in schools)
{
school.teachers = school.teacherIds.Select(id => teachersDic[id]).ToList();
school.students = school.studentIds.Select(id => studentsDic[id]).ToList();
}
foreach (var teacher in teachers)
{
teacher.students = teacher.studentIds.Select(id => studentsDic[id]).ToList();
teacher.school = schoolsDic[teacher.schoolId];
}
foreach (var student in students)
{
student.Teacher = teachersDic[student.id];
student.school = schoolsDic[student.schoolId];
}
}
}