Entity Framework объект LINQ запрос Время ожидания проблемы

Я попытался изменить строку подключения, чтобы включить расширенное время ожидания, и я подтвердил, что на стороне сервера sql представление, которое передает мой объект EF, выполняется в течение нескольких секунд и возвращает в общей сложности 3000 или менее записей.

НО, когда я пытаюсь запустить его с помощью кода, у меня сейчас возникают проблемы с тайм-аутом, и я искал несколько советов, чтобы решить эту проблему. Я получаю "Время выполнения истекло. Период ожидания истек до завершения операции или сервер не отвечает". Большинство решений, которые я нахожу по конкретной ошибке, рекомендуют модификации строки подключения ИЛИ что-то подобное this.context.CommandTimeout... которое я не могу понять, как использовать в этой ситуации.

Я включил метод, который я использую, чтобы получить нужные данные. Если есть более эффективный способ, пожалуйста, дайте мне знать.

Входные аргументы:

  • int? inputSKU = null
  • int? inputStoreNum = null
  • DateTime? inputStartDate = null

Цель состоит в том, чтобы вернуть полный список.

И он зависает, потому что пропускает все условные биты:var qUniqueOffers = query.GroupBy(q => q.Plan_Number).ToList();

Спасибо.


private List<PromotionItem> QueryPromotion(int? inputSKU, int? inputStoreNum, DateTime? inputStartDate)
{
    log.Info("Client requested QueryPromotion");
    List<PromotionItem> resultQuery = new List<PromotionItem>();

    try
    {
        using (DWH_Entities db = new DWH_Entities())
        {
            var query = db.vw_Web_Promotion.AsQueryable();

            // filter promotion results that don't match SKU#
            if (inputSKU != null)
                query = query.Where(q => q.Sku_Number == inputSKU);
            // filter promotion results that don't match Store Num
            if (inputStoreNum != null)
                query = query.Where(q => q.Store_Number == inputStoreNum);
            // filter promotion results that don't match Promotion Start Date
            if (inputStartDate != null)
                query = query.Where(q => q.Start_Date >= inputStartDate);
            // Group promotions By Plan Number ('Promotion ID')
            var qUniqueOffers = query
                                .GroupBy(q => q.Plan_Number)
                                .ToList();
            // Select first from each group to get unique details
            var qOffers = qUniqueOffers
                        .Select(g => g.OrderBy(gi => gi.Plan_Number).First())
                        .ToList();

            foreach (var qo in qOffers)
            {
                resultQuery.Add(new PromotionItem
                {
                    PromotionNumber = qo.Plan_Number.Trim(),
                    PromotionDescription = qo.Plan_Description.Trim(),
                    StartDate = qo.Start_Date,
                    EndDate = qo.End_Date
                });
            }
        }
    }
    catch (Exception e)
    {
        log.Error("[" + e.TargetSite + "] | " + e.Message);
        throw e;
    }

    return resultQuery;
}

2 ответа

Решение
// Group promotions By Plan Number ('Promotion ID')
var qUniqueOffers = query
                    .GroupBy(q => q.Plan_Number)
                    .ToList();
// Select first from each group to get unique details
var qOffers = qUniqueOffers
            .Select(g => g.OrderBy(gi => gi.Plan_Number).First())
            .ToList();

То, как вы написали вышеупомянутый LINQ, означает, что вы перетаскиваете много данных по проводам (первое ToList), а затем получить подмножество данных (используя First а второй ToList). Попробуйте изменить его на:

// Group promotions By Plan Number ('Promotion ID')
var qUniqueOffers = query
                    .GroupBy(q => q.Plan_Number)
// Select first from each group to get unique details
var qOffers = qUniqueOffers
            .Select(g => g.OrderBy(gi => gi.Plan_Number).First())
            .ToList();

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

Как /questions/33230703/linq-to-entities-orderbytolist-ili-tolistorderby/33230716#33230716 говорится:

ToList () всегда вынуждает все, что впереди, сразу оценивать, в отличие от отложенного выполнения.

Если вы используете последнюю версию EF, сделайте следующее, чтобы увеличить время ожидания:

using (DWH_Entities db = new DWH_Entities())
{
    db.Database.CommandTimeout = 300;
    ...

Если вы хотите записи в минимальное время, попробуйте следующее:

var temp = query.ToList();
var qUniqueOffers = temp.GroupBy(q => q.Plan_Number)
                                .ToList();
Другие вопросы по тегам