gpt4 book ai didi

c# - EF Core 慢速批量插入(约 80k 行)

转载 作者:行者123 更新时间:2023-12-02 01:52:05 25 4
gpt4 key购买 nike

我有一个 Save 对象,它有多个关联的集合。对象的总大小如下:

enter image description here

对象之间的关系可以从该映射中推断出来,并且在数据库中似乎得到了正确的表示。查询也很好。

modelBuilder.Entity<Save>().HasKey(c => c.SaveId).HasAnnotation("DatabaseGenerated",DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Save>().HasMany(c => c.Families).WithOne(x => x.Save).HasForeignKey(x => x.SaveId);
modelBuilder.Entity<Save>().HasMany(c => c.Countries).WithOne(x => x.Save).HasForeignKey(x => x.SaveId);
modelBuilder.Entity<Save>().HasMany(c => c.Provinces).WithOne(x => x.Save).HasForeignKey(x => x.SaveId);
modelBuilder.Entity<Save>().HasMany(c => c.Pops).WithOne(x => x.Save).HasForeignKey(x => x.SaveId);
modelBuilder.Entity<Country>().HasOne(c => c.Save);
modelBuilder.Entity<Country>().HasMany(c => c.Technologies).WithOne(x => x.Country).HasForeignKey(x => new {x.SaveId, x.CountryId});
modelBuilder.Entity<Country>().HasMany(c => c.Players).WithOne(x => x.Country).HasForeignKey(x => new {x.SaveId, x.CountryId});
modelBuilder.Entity<Country>().HasMany(c => c.Families).WithOne(x => x.Country).HasForeignKey(x => new {x.SaveId, x.OwnerId});
modelBuilder.Entity<Country>().HasMany(c => c.Provinces).WithOne(x => x.Owner);
modelBuilder.Entity<Country>().HasKey(c => new { c.SaveId, c.CountryId });
modelBuilder.Entity<Family>().HasKey(c => new { c.SaveId, c.FamilyId });
modelBuilder.Entity<Family>().HasOne(c => c.Save);
modelBuilder.Entity<CountryPlayer>().HasKey(c => new { c.SaveId, c.CountryId, c.PlayerName });
modelBuilder.Entity<CountryPlayer>().HasOne(c => c.Country);
modelBuilder.Entity<CountryPlayer>().Property(c => c.PlayerName).HasMaxLength(100);
modelBuilder.Entity<CountryTechnology>().HasKey(c => new { c.SaveId, c.CountryId, c.Type });
modelBuilder.Entity<CountryTechnology>().HasOne(c => c.Country);
modelBuilder.Entity<Province>().HasKey(c => new { c.SaveId, c.ProvinceId });
modelBuilder.Entity<Province>().HasMany(c => c.Pops).WithOne(x => x.Province);
modelBuilder.Entity<Province>().HasOne(c => c.Save);
modelBuilder.Entity<Population>().HasKey(c => new { c.SaveId, c.PopId });
modelBuilder.Entity<Population>().HasOne(c => c.Province);
modelBuilder.Entity<Population>().HasOne(c => c.Save);

我从文件中解析整个save,因此无法一一添加所有集合。解析后,我有一个包含所有关联集合的Save,添加了多达 80k 个对象,但这些对象都不存在于数据库中。

然后,当我调用 dbContext.Add(save) 时,处理时间大约为 44 秒,RAM 使用量从 100mb 上升到大约 700mb。

然后,当我调用 dbContext.SaveChanges() (我还尝试了 EF 扩展中的常规 BulkSaveChanges() 方法,没有显着差异)时,需要额外的 60 秒,RAM 使用量高达 1.3Gb。

这是怎么回事?为什么这么长的时间和这么多的内存使用量?实际上传到数据库只需要最后5秒左右。

PS:我也尝试禁用更改检测,但没有效果。

PS2:实际使用情况和评论中要求的完整代码:

public class HomeController : Controller
{
private readonly ImperatorContext _db;

public HomeController(ImperatorContext db)
{
_db = db;
}

[HttpPost]
[RequestSizeLimit(200000000)]
public async Task<IActionResult> UploadSave(List<IFormFile> files)
{
[...]
await using (var stream = new FileStream(filePath, FileMode.Open))
{
var save = ParadoxParser.Parse(stream, new SaveParser());
if (_db.Saves.Any(s => s.SaveKey == save.SaveKey))
{
response = "The save you uploaded already exists in the database.";
}
else
{
_db.Saves.Add(save);
}
_db.BulkSaveChanges();
}
[...]
}

}

最佳答案

从 nuget 下载 EFCore.BulkExtensions

删除“_db.BulkSaveChanges();”并替换“_db.Saves.Add(save);”使用此代码

_db.Saves.BulkInsert(save);

关于c# - EF Core 慢速批量插入(约 80k 行),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59954097/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com