Самый эффективный способ вставить отношения родитель-ребенок с точки зрения использования памяти? - PullRequest
1 голос
/ 16 апреля 2019

В настоящее время я работаю над проектом ASP.NET Core, который использует Entity Framework Core с поставщиком базы данных SQL Server.У меня есть несколько сущностей с несколькими взаимосвязями между ними, и я хочу узнать, как наиболее эффективно вставить эти сущности в базу данных.

Я попробовал советы из Самый быстрый способ вставки в сущностьFramework относительно вставки в пакетах, вызовите SaveChanges() после 100, 1000 сущностей и избавьтесь от контекста.Однако использование памяти возрастает до 1 ГБ или более, и поток не поддерживает свойства навигации, а имеющиеся у меня данные являются лишь подмножеством всего набора данных.Данные взяты из внешнего вызова Web API, в котором я сериализируюсь в сущности.

Примеры моих сущностей (упрощенные, не реальные сущности в моем проекте):

Студент :

public class Student
{
 public int StudentId {get;set;}
 public string StudentName {get;set;}
 public List<Course> Course{ get; } = new List<Course>();
}

Курс :

public class Course
{
 public int CourseId {get;set;}
 public string CourseName {get;set;}
 public List<Grade> Grades{ get; } = new List<Grade>();
}

Оценка :

public class Grade
{
 public int GradeId {get;set;}
 public string GradeValue{get;set;}
}

Студент имеет отношение один-ко-многим с курсом.

курс имеет отношение один-ко-многим с оценкой.

Приближение количества данныхУ меня есть:

  • Студенты: ~ 100-200
  • Курсы: ~ 5 000 до 10 000
  • Оценки: ~ 30

Как видите, огромное количество сущностей может быть довольно большим, и отношения между ними должны быть строгими.Прямо сейчас мне удалось организовать так, что у меня есть словарь студентов как ключ и List<Course> как значение , и каждый курс имеет List<Grade>.List<Grade> заполняется во время анализа ответа от внешнего вызова Web API.Использование словаря при создании словаря увеличивается со 100 МБ до 300-400 МБ.

Это мой текущий код (фрагмент):

Dictionary<Student,List<Courses>> studentMap;
DbContext context = null;
try
{
 context = new DbContext();
 context.ChangeTracker.AutoDetectChangesEnabled = false;
 foreach (var student in studentMap)
 {
   numberOfStudents++;
   context = AddToContext(context,student,numberOfStudents,10,true);
 }
 context.SaveChanges();
}


private DbContext AddToContext(DbContext context, KeyValuePair<Student, List<Course>> entity, int numberOfStudents, int commitCount, bool recreateContext)
{
 Student entityStudent = entity.Key;
 List<Course> list = entity.Value; //This list ranges from 5000-10000 as mentioned before.
 entityStudent.Courses.AddRange(list); 
 context.Set<Student>().Add(entityStudent);

 if(numberOfStudent % commitCount == 0)
 { 
   context.SaveChanges();
   if(recreateContext)
   {
    context.Dispose();
    context = new DbContext();
    context.ChangeTracker.AutoDetectChangesEnabled = false;
   }
 }
 return context;
}

Вся памятьиспользование увеличивается до 1 ГБ, время, необходимое для вставки около 100 студентов с 30 000 курсов и 3 классов для каждого курса, занимает около 5 минут.Есть ли лучший подход к этому?Тем более, что это вложенный объект со свойствами навигации.

С наилучшими пожеланиями,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...