我目前正在研究一个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;}
}
学生与课程之间具有一对多关系。
课程与成绩之间具有一对多关系。
我拥有的数据量的近似值:
如您所见,实体的绝对数量可能很大,并且它们之间的关系必须严格。现在,我已经设法组织好了,使我有一个词典学生作为 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分钟。有什么更好的办法吗?特别是因为这是具有导航属性的嵌套实体。
最好的问候,