简体   繁体   English

实体框架对象LINQ查询超时问题

[英]Entity Framework object LINQ query Timeout issues

I've attempted to modify my connection string to include an extended timeout and I've confirmed that on the sql server side the view that feeds my EF Object executes within seconds and returns a total of 3000 or less records. 我试图修改我的连接字符串以包括延长的超时时间,并且我已经确认在sql服务器端,用于馈送EF对象的视图会在几秒钟内执行,并返回总计3000条或更少的记录。

BUT when I attempt to run it via code I am now running into Timeout issues and I was seeking some advice to fix this issue. 但是,当我尝试通过代码运行它时,我现在遇到了超时问题,我正在寻求一些建议来解决此问题。 I get "Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding." 我收到“执行超时到期。在操作完成之前超时或服务器没有响应的超时时间。” Most solutions I find on the specific error recommend connection string modifications OR something along this.context.CommandTimeout... which I cannot figure out how to use in this situation. 我发现的针对特定错误的大多数解决方案都建议修改连接字符串或this.context.CommandTimeout ...中的某些内容,在这种情况下我不知道该如何使用。

I've included the Method I use to acquire the desired data. 我已经包括了用来获取所需数据的方法。 If there is a more efficient way please let me know. 如果有更有效的方法,请告诉我。

The input arguments are: 输入参数为:

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

The intent is to return the full list. 目的是返回完整列表。

And it hangs at, because it skips all the conditional bits: var qUniqueOffers = query.GroupBy(q => q.Plan_Number).ToList(); 它会var qUniqueOffers = query.GroupBy(q => q.Plan_Number).ToList(); ,因为它会跳过所有条件位: var qUniqueOffers = query.GroupBy(q => q.Plan_Number).ToList();

Thank you. 谢谢。


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;
}

If you are using latest EF version do the following to increase timeout: 如果您使用的是最新的EF版本,请执行以下操作以增加超时:

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

If you want records in the minimum time, try following: 如果要在最短时间内记录,请尝试以下操作:

var temp = query.ToList();
var qUniqueOffers = temp.GroupBy(q => q.Plan_Number)
                                .ToList();
// 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();

The way you have written the above LINQ means you are pulling a lot of data over the wire (the first ToList ) and then getting a subset of the data (using First and the second ToList ). 上面LINQ的编写方式意味着您要通过网络(第一个ToList )提取大量数据,然后获取数据的子集(使用First和第二个ToList )。 Consider changing it to: 考虑将其更改为:

// 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();

This should result in much less data being sent from the database - which will hopefully make it faster. 这将导致从数据库发送的数据少得多 -希望可以使其更快。

As https://stackoverflow.com/a/13827077/34092 states: https://stackoverflow.com/a/13827077/34092所述:

ToList() always forces everything ahead of it to evaluate immediately, as opposed to deferred execution. 与延迟执行相反,ToList()始终强制其前面的所有内容立即进行评估。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM