Итак, моя проблема в том, что мне нужно запустить приложение ASP. NET, работающее в 32-битном режиме. Но мне нужно обработать кучу записей, и это вносит огромные изменения в базу данных. В случае чего-то не получается, я должен поместить весь процесс в транзакцию. Я подумал, что если я использую DBContext.SaveChanges()
после каждых 10000 обработанных записей и избавляюсь от ссылок и т. Д. c. так что GC
может сделать свою работу, может решить мою проблему, но это не так. Проблема в том, что каждый процесс, использующий БД (я имею в виду операции CRUD), значительно замедляется (даже в 10 раз медленнее или около того).
Поэтому мой код выглядит примерно так:
public void StartProcess()
{
localScopeCtx = cont.Resolve<IApplicationDbContext>();
IDbContextTransaction trans = localScopeCtx.BeginTransaction();
int take = 10000;
int index = 1;
while (index <= needToProcess)
{
var records = GetRecords(take)
List<obj> recordsToDelete;
ProcessRecords(take, out recordsToDelete);
localScopeCtx.Records.RemoveRange(recordsToDelete);
localScopeCtx.SaveChanges();
DetachAllEntities(localScopeCtx);
}
trans.Commit();
}
public void DetachAllEntities(IApplicationDbContext dbContext)
{
var changedEntriesCopy = dbContext.ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added ||
e.State == EntityState.Modified ||
e.State == EntityState.Deleted ||
e.State == EntityState.Unchanged)
.ToList();
foreach (var entry in changedEntriesCopy)
entry.State = EntityState.Detached;
}
В первом л oop все нормально. Это быстро и делает свою работу как шарм. Но после одного localScopeCtx.SaveChanges()
все замедляется, как я сказал. Я думаю, это потому, что EF на самом деле не отправляет изменения в базу данных, а сохраняет их в памяти (в соответствии с использованием памяти), но более умным способом, которым он никогда не исчерпывает себя (возможно, использование виртуальной памяти или итак).
Любые предложения, что может быть решением?
РЕДАКТИРОВАТЬ: Добавление метода DetachAllEntities
к процессу;