В настоящее время я работаю над проектом 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 минут.Есть ли лучший подход к этому?Тем более, что это вложенный объект со свойствами навигации.
С наилучшими пожеланиями,