sql-server - 在内存使用方面插入父子关系的最有效方法是什么?
问题描述
我目前正在开发一个使用 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;}
}
学生与课程是一对多的关系。
课程与成绩是一对多的关系。
我拥有的数据量的近似值:
- 学生:~100-200
- 课程:~5 000 到 10 000
- 等级:~30
如您所见,实体的数量可能非常大,它们之间的关系需要严格。现在我已经设法组织这样我有一个学生字典作为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 分钟。有没有更好的方法呢?特别是因为这是一个具有导航属性的嵌套实体。
此致,
解决方案
推荐阅读
- java - 将子类传递给带有抽象类参数的方法
- python - 序列化 ctype union
- ruby-on-rails - 将项目克隆到特定文件夹
- python-3.x - 运行 python 文件以使用强化学习训练 GAN
- angular - ChangeDetection OnPush:直接调用时不触发 ngFor
- c++11 - 为什么虚拟析构函数需要操作符删除?
- c# - 向成员列表添加值
- python - 如何使用自定义颜色绘制散点图
- c# - 如何绑定到现有对象集合的一个属性
- report - Google Ad Manager COLUMNS_NOT_SUPPORTED_FOR_REQUESTED_DIMENSION 报告错误