一、EF Core 批量添加数据 问题详解 AddRange()
问题整理:
1.对于批量写入数据,每次几万条情况 使用 Add() 方法不合理
2.使用AddRange() 每次批量写入数据也要有个数限制,不然也会异常报错
3.批量写入数据,如果Sqlserver 日志文件或者磁盘空间占满也会抛出异常。
4.批量写入需要控制对象的字符数量,字符数量大的写入慢没太多优化空间,看你的磁盘和硬件情况了。
批量数据写入解决方案:
1.写入每条数据字符量尽可能小
2.分段写入,避免内存不足异常
3.使用第三方库,协助增速写入:Z.EntityFramework.Extensions.EFCore
更多参考:
二、批量数据分段写入富文本字符数量较大, 使用AddRange()
如果不分段写入,内存不足会抛出异常
static void Test3()
{
// EF Core 批量添加数据 问题详解 AddRange()
try
{
QLSingleContext _context = new QLSingleContext();
ArtileNews news = _context.ArtileNews.Find(6);
DateTime start = DateTime.Now;
List<ArticleInfo> artList = new List<ArticleInfo>();
for (int i = 0; i < 50000; i++)
{
ArticleInfo model = new ArticleInfo();
model.Title = news.Title;
// model.Content = news.Content;
model.Content = "内容稍的测试数据";
model.ViewCount = 0;
model.LastEditTime = DateTime.Now;
model.EmpId = 4;
artList.Add(model);
}
Console.WriteLine($"内存组建完成使用{(DateTime.Now - start).TotalSeconds}秒");
//1.批量添加的个数是有上限的,根据自己电脑内存而定
//2.单条数据字符空间大慢
//3.数据太多一次添加太慢
_context.ArticleInfos.AddRange(artList);
_context.SaveChanges();
DateTime end = DateTime.Now;
Console.WriteLine($"添加成功了{artList.Count}条数据");
Console.WriteLine($"总共使用{(end - start).TotalSeconds}秒");
}
catch (Exception ex)
{
throw ex;
}
}
分段写入代码处理:
//分段插入----此方法不奏效,但可以解决内存不足的bug
static void MyAddRange(QLSingleContext _context, List<ArticleInfo> artList)
{
//每次插入2000 条
int num = 0;
while (true)
{
var temp = artList.Skip(num).Take(10000).ToList();
if (temp.Count == 0)
break;
//使用默认
_context.ArticleInfos.AddRange(temp);
_context.SaveChanges();
num += temp.Count;
}
}
插入非富文本,字符量小的数据 5万条:
三、批量查询想增加查询速度,可以取消上下文监听
//查询禁用跟踪
//_context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
// _context.ChangeTracker.AutoDetectChangesEnabled = false;
更多: