就内存使用而言,插入父子关系的最有效方法是什么?

时间:2019-04-16 12:53:02

标签: sql-server database entity-framework asp.net-core entity-framework-core

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

我尝试了Fastest Way of Inserting in Entity Framework中有关批量插入,在100,1000个实体后调用SaveChanges()并处理上下文的提示。但是,内存使用量增加到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;}
}

学生与课程之间具有一对多关系。

课程与成绩之间具有一对多关系。

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

  • 学生:〜100-200
  • 课程:〜5 000至10000
  • 成绩:〜30

如您所见,实体的绝对数量可能很大,并且它们之间的关系必须严格。现在,我已经设法组织好了,使我有一个词典学生作为 key 和一个List<Course>作为 value ,每个课程有一个List<Grade>。在解析来自外部Web API调用的响应期间,将填充List<Grade>。创建字典时,内存使用量从大约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名学生(共3万门课程,每门课程分为3个等级)所需的时间大约为5分钟。有什么更好的办法吗?特别是因为这是具有导航属性的嵌套实体。

最好的问候,

0 个答案:

没有答案