我有一个Save
具有多个关联集合的对象。对象的总大小如下:
对象之间的关系可以从该映射中推断出来,并且在数据库中似乎得到了正确的表示。查询也很好。
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()
(我也尝试过常规的BulkSaveChanges()
EF 扩展中的方法(没有显着差异)需要额外的 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();
}
[...]
}
}