Можно ли улучшить время разогрева EF6? - PullRequest
0 голосов
/ 01 октября 2018

У меня есть приложение, в котором я проверяю следующее поведение: первые запросы после длительного периода бездействия занимают много времени, а иногда и время ожидания.Можно ли контролировать, как структура сущности управляет удалением объектов?Возможно ли пометить некоторых сущностей, чтобы они никогда не были уничтожены?... чтобы избежать / улучшить время прогрева?

С уважением,

1 Ответ

0 голосов
/ 01 октября 2018

Причины того, что аналогичные запросы будут иметь улучшенное время отклика, разнообразны.

  • Большинство систем управления базами данных кэшируют части извлеченных данных, поэтому подобные запросы в ближайшем будущем будут выполняться быстрее.Если вы выполните запрос Teachers with their Students, то таблица Teachers будет объединена с таблицей Students.Этот результат соединения довольно часто кешируется некоторое время.Следующий запрос для Teachers with their Students будет повторно использовать этот результат объединения и, следовательно, станет быстрее
  • DbContext кэширует запрашиваемый объект.Если вы выберете учителя Single или Find, он будет сохранен в локальной памяти.Это должно быть в состоянии определить, какие элементы изменены, когда вы звоните SaveChanges.Если вы Find снова наберете Teacher, этот запрос будет быстрее.Я не уверен, произойдет ли то же самое, если вы запросите 1000 Teachers.
  • Когда вы создаете объект DbContext, инициализатор проверяется, чтобы увидеть, была ли модель изменена или нет.

Так что может показаться неуместным Dispose() созданного DbContext, но вы видите, что большинство людей поддерживают DbContext в течение довольно короткого времени:

using (var dbContext = new MyDbContext(...))
{
    var fetchedTeacher = dbContext.Teachers
        .Where(teacher => teacher.Id = ...)
        .Select(teacher => new
        {
            Id = teacher.Id,
            Name = teacher.Name,
            Students = teacher.Students.ToList(),
         })
         .FirstOrDefault();
    return fetchedTeacher;
}
// DbContext is Disposed()

ВНа первый взгляд может показаться, что было бы лучше сохранить DbContext живым.Если кто-то запрашивает тот же Teacher, DbContext не нужно будет запрашивать его у базы данных, он может вернуть локального Учителя ..

Однако сохранение DbContext в живых может привести к тому, чтовы получаете неверные данные.Если кто-то еще изменит Teacher между вашим первым и вторым запросом для этого Teacher, вы получите старые Teacher данные.

Следовательно, разумно сохранить время жизни DbContextкак можно короче.

Что я могу сделать, чтобы улучшить скорость первого запроса?

Да, вы можете!

Первое, что вы можете сделать, это установить инициализацию вашей базы данных так, чтобы она не проверяла существование и модель базы данных.Конечно, вы можете сделать это только тогда, когда уверены, что ваша база данных существует и не изменилась.

// constructor; disables initializer
public SchoolDBContext() : base(...)
{            
    //Disable initializer
    Database.SetInitializer<SchoolDBContext>(null);
}

Другое дело, если вы уже выбрали объект для обновления базы данных, и выВы уверены, что никто не изменил объект, вы можете Attach его, вместо того, чтобы извлекать его снова, , как показано в этом вопросе

Нормальное использование:

// update the name of the teacher with teacherId
void ChangeTeacherName(int teacherId, string name)
{
    using (var dbContext = new SchoolContext(...))
    {
        // fetch the teacher, change the name and save
        Teacher fetchedTeacher = dbContext.Teachers.Find(teacherId);
        fetchedTeader.Name = name;
        dbContext.SaveChanges();
    }
}

Использование Attach для обновления ранее загруженного Учителя:

void ChangeTeacherName (Teacher teacher, string name)
{
    using (var dbContext = new SchoolContext(...))
    {
          dbContext.Teachers.Attach(teacher);
          dbContext.Entry(teacher).Property(t => t.Name).IsModified = true;
          dbContext.SaveChanges();
    }
}

Использование этого метода не требует повторной загрузки Учителя.Во время SaveChanges проверяется значение IsModified всех свойств всех Attached элементов.При необходимости они будут обновлены.

...