首页 > 解决方案 > 在内存使用方面插入父子关系的最有效方法是什么?

问题描述

我目前正在开发一个使用 Entity Framework Core 和数据库提供程序 SQL Server 的 ASP.NET Core 项目。我有多个实体,它们之间有多种关系,我想学习如何以最有效的方式将这些实体插入数据库。

我已经尝试过在实体框架中插入的最快方式中关于批量插入、SaveChanges()在 100,1000 个实体后调用和处理上下文的提示。但是,内存使用量上升到 1GB 或更多,并且线程不支持导航属性,我拥有的数据只是整个数据集的一个子集。数据来自外部 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;}
}

学生与课程是一对多的关系。

课程与成绩是一对多的关系。

我拥有的数据量的近似值:

如您所见,实体的数量可能非常大,它们之间的关系需要严格。现在我已经设法组织这样我有一个学生字典作为key和 aList<Course>作为value,每个 Course 都有一个List<Grade>. List<Grade>在解析来自外部 Web API 调用的响应期间填充。创建字典时,内存使用量从大约 100MB 上升到 300-400MB。

这是我当前的代码(片段):

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;
}

整个内存使用量上升到 1GB 以上,插入大约 100 名 30 000 门课程和每门课程 3 个等级的学生所需的时间大约需要 5 分钟。有没有更好的方法呢?特别是因为这是一个具有导航属性的嵌套实体。

此致,

标签: sql-serverdatabaseentity-frameworkasp.net-coreentity-framework-core

解决方案


推荐阅读