У меня есть Save
объект, с которым связано несколько коллекций. Общий размер объектов выглядит следующим образом:
![enter image description here](https://i.stack.imgur.com/FQpxI.png)
Отношения между объектами могут быть выведены из этого отображения и, кажется, правильно представлены в базе данных. Кроме того, запросы работают просто отлично.
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
со всеми связанными коллекциями, добавляя до 80 тыс. Объектов, ни один из которых не присутствует в базе данных.
Затем, когда я вызываю dbContext.Add(save)
, это занимает около 44 секунд, чтобы процесс, с использованием ОЗУ, увеличивающимся с 100 МБ до примерно 700 МБ.
Затем, когда я вызываю dbContext.SaveChanges()
(я также попробовал обычный метод BulkSaveChanges()
из EF Extensions без существенной разницы), требуется дополнительные 60 с. , с использованием оперативной памяти до 1,3 ГБ.
Что здесь происходит? Почему так долго и так много использования памяти? Фактическая загрузка в базу данных занимает всего около 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();
}
[...]
}
}