【问题标题】:Entity Framework object LINQ query Timeout issues实体框架对象 LINQ 查询超时问题
【发布时间】:2017-06-23 05:10:14
【问题描述】:

我已尝试修改我的连接字符串以包含延长的超时时间,并且我已确认在 sql server 端,提供我的 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;
}

【问题讨论】:

  • 哪一行产生了Execution Timeout Expired 异常?可以给我们截图吗?
  • @mjwills 引用此代码块。第 22 行。它到达了我在此处设置的断点,当我继续运行时,它会转动 30 秒左右,然后引发超时异常。 var qUniqueOffers = query.GroupBy(q => q.Plan_Number).ToList();
  • TejasVaishnav 发布了一个延长我的超时时间的解决方案,但遗憾的是,我认为我的查询/应用程序没有得到优化,因为它在 300 秒后仍然超时。我会尝试重写。
  • 如果从 var qUniqueOffers = query .GroupBy(q =&gt; q.Plan_Number) .ToList() 中删除 ToList 会发生什么?这会改善情况吗?
  • @mjwills 你知道吗。我认为这成功了。非常感谢。

标签: c# entity-framework linq timeout executiontimeout


【解决方案1】:

如果您使用的是最新的 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();

【讨论】:

  • TejasVaishnav 谢谢。使用 EF6,这有助于解决我最初关于延长超时的问题。由于我分配给我的对象的值,我确实必须将“context”修改为“db”,但它延长了运行时间 db.Database.CommandTimeout = 300;
  • 我的错,为他人编辑,感谢告知
  • 我不知道你为什么不喜欢这个答案。 db.Database.CommandTimeout 工作。这么多人回答复杂,你的答案很完美。保持良好的工作。先生,您好。
【解决方案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();

这应该会导致从数据库发送的数据大大减少 - 这有望使其更快。

正如https://stackoverflow.com/a/13827077/34092 所说:

ToList() 总是强制它前面的所有东西立即评估, 而不是延迟执行。

【讨论】:

  • mjwills 感谢您的详细回答。我将补充一点,因此我必须将 .First() 修改为 .FirstorDefault() 因为它引发了语法异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-15
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 2011-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多