Циклические ссылки при сериализации - 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];
            }
        }
    }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 3.875 из 5