C# EF Query оптимизация - PullRequest
       1

C# EF Query оптимизация

0 голосов
/ 03 марта 2020

У меня есть следующая функция, использующая Entity Framework, которая проверяет таблицу БД на наличие данных о продуктах с истекшим сроком действия. Весь запрос кажется чрезвычайно медленным, и мне интересно, есть ли лучший / более эффективный способ адаптации этого запроса, поскольку всегда есть большой объем данных для очистки иногда до 3 тыс. элементов.

Это просто элемент выбора, который может занять 4-10 минут в зависимости от размера базы данных в день.

Формат даты и времени Пример = 2021- 03-31T23: 59: 59.000

using (ProductContext db = new ProductContext())
{
    log.Info("Checking for expired data in the Product Data db");
    //rule = now - configured hours, default = 2 hours in past.
    var checkWindow = Convert.ToInt32(PRODUCTMAPPING_CONFIG.MinusExpiredWindowHours);
    var dtCheck = Convert.ToDateTime(DateTime.Now.AddHours(-checkWindow).ToString("s"));

    var rowData = db.ProductData.Where(le => Convert.ToDateTime(le.ProductEndDate.Value.ToString().Trim()) < dtCheck).ToList();

    rowData.ForEach(i => {log.Debug($"DB Row ID {i.Id} with Product ID Value: {i.ProductUid} has expired with Product End Date: {i.ProductEndDate}, marked for removal."); });

    log.Info($"Number of expired Products being removed: {rowData.Count()}");

    db.ProductData.RemoveRange(rowData);
    db.SaveChanges();

    log.Info(rowData.Count == 0
        ? "No expired data present."
        : $"Number of expired assets Successfully removed from database = {rowData.Count}");
}

Заранее спасибо

РЕДАКТИРОВАТЬ ::

Благодаря всем предложениям, которые я буду рассматривать комментарии ORM, сделанные Panagiotis Kanavos ниже в отношении прямых запросов для этого типа элемента, и изменили тип столбца на основе комментария от Panagiotis Kanavos снова. Наконец, комментарий .ToList от jdweng немедленно убрал отставание, так что это, по крайней мере, сейчас заставляет меня двигаться быстрее, пока я смотрю на предложения Panagiotis Kanavos, поскольку думаю, что это, вероятно, лучший путь вперед?

Более быстрый код сейчас:

using (ProductContext db = new ProductContext())
{
    log.Info("Checking for expired data in the Product Data db");
    //rule = now - configured hours, default = 2 hours in past.
    var checkWindow = Convert.ToInt32(PRODUCTMAPPING_CONFIG.MinusExpiredWindowHours);
    var dtCheck = Convert.ToDateTime(DateTime.Now.AddHours(-checkWindow).ToString("s"));

    // Ammended DB Table from nvarchar to DateTime to allow direct comparison based on comment by: Panagiotis Kanavos
    // Removed ToList() which returned the IEnumerable immediately based on comment by: jdweng
    var rowData = db.ProductData.Where(le => le.ProductEndDate < dtCheck);

    log.Info($"Number of expired Products being removed: {rowData.Count()}");

    // added print out on debug only.
    if(log.IsDebugEnabled)
        rowData.ToList().ForEach(i => {log.Debug($"DB Row ID {i.Id} with Product ID Value: {i.ProductUid} has expired with Product End Date: {i.ProductEndDate}, marked for removal."); });


    var rowCount = rowData.Count();

    db.ProductData.RemoveRange(rowData);
    db.SaveChanges();

    log.Info(rowCount == 0
        ? "No expired data present."
        : $"Number of expired assets Successfully removed from database = {rowCount}");
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...