簡體   English   中英

實體框架導致超時錯誤

[英]Entity Framework causing Timeout Error

我正在使用以下實體框架查詢。 我知道這里有很多事情,但我希望有一個人可能能夠發現問題。

var lineItems = from li in Repository.Query<CostingLineItem>()

                let cid = (li.ParentCostingPackage != null) ?
                    li.ParentCostingPackage.ParentCostingEvent.ProposalSection.Proposal.Costing.Id :
                    li.ParentCostingEvent.ProposalSection.Proposal.Costing.Id

                where cid == costingId &&
                    li.OriginalProductId.HasValue &&
                    (li.Quantity.HasValue && li.Quantity.Value > 0) &&  // li.QuantityUnitMultiplier
                    Classifications.Contains(li.OriginalProduct.ClassificationEnumIndex)

                let selectedChoiceId = li.OriginalPackageOptionId.HasValue ?
                    (from c in li.OriginalPackageOption.CostingLineItems
                        orderby (c.IsIncluded ?? false) ? -2 : (c.IsDefaultItem ?? false) ? -1 : c.Id
                        select (int)c.OriginalPackageOptionChoiceId).FirstOrDefault() :
                    0

                where selectedChoiceId == 0 || (li.OriginalPackageOptionChoiceId.HasValue && li.OriginalPackageOptionId.Value == selectedChoiceId)

                let hasProviderAvailable = li.OriginalProductItem.ProductItemVendors.Any(
                    piv => piv.ProductPricings.Any(pp => pp.ProductItemVendor.CompanyId != null || pp.ProductItemVendor.HotelId != null))

                select new
                {
                    LineItem = li,
                    ProductItem = li.OriginalProductItem,
                    Product = li.OriginalProduct,
                    Vendors = li.CostingLineItemVendors,
                    HasProviderAvailable = hasProviderAvailable
                };

這樣,此查詢會生成以下運行時錯誤:

等待操作超時

如果我將聲明selectedChoiceId的部分更改為以下內容,則錯誤消失:

let selectedChoiceId = 0

任何人都可以看到該代碼如何一直導致超時錯誤?

(注意:此代碼是已經運行了幾年的大型應用程序的一部分。所以我真的不認為這與連接字符串或類似的東西有任何關系。如果我進行上述更改,它會始終如一地工作。)

我認為這會給你一個更好的性能,但不確定它是否能解決問題:

let selectedChoiceId = li.OriginalPackageOptionId.HasValue
    ? (from c in li.OriginalPackageOption.CostingLineItems
        let cOrder = (c.IsIncluded ?? false) ? -2 : (c.IsDefaultItem ?? false) ? -1 : c.Id
        orderby cOrder
        select (int) c.OriginalPackageOptionChoiceId).FirstOrDefault()
    : 0

可以通過多種方式簡化查詢,這樣可以更容易地通過數據庫引擎進行優化。

首先,您可以刪除多個空檢查( HasValue ),因為它們與SQL無關,但它們會使生成的SQL膨脹。

其次,我認為這個涉及selectedChoiceId檢查可以大大簡化。 這就是我認為該陳述可能是這樣的:

from li in Repository.Query<CostingLineItem>()

let cid = (li.ParentCostingPackage != null) ?
    li.ParentCostingPackage.ParentCostingEvent.ProposalSection.Proposal.Costing.Id :
    li.ParentCostingEvent.ProposalSection.Proposal.Costing.Id

where cid == costingId &&
    li.OriginalProductId.HasValue &&
    li.Quantity > 0 &&  // no null check
    Classifications.Contains(li.OriginalProduct.ClassificationEnumIndex)

let selectedChoiceId = (from c in li.OriginalPackageOption.CostingLineItems
        orderby c.IsIncluded ? -2 : c.IsDefaultItem ? -1 : c.Id // no null checks
        select (int)c.OriginalPackageOptionChoiceId).FirstOrDefault()

where !li.OriginalPackageOptionId.HasValue || li.OriginalPackageOptionId == selectedChoiceId

let hasProviderAvailable = li.OriginalProductItem.ProductItemVendors.Any(
    piv => piv.ProductPricings.Any(pp => pp.ProductItemVendor.CompanyId != null || pp.ProductItemVendor.HotelId != null))

select new
{
    LineItem = li,
    ProductItem = li.OriginalProductItem,
    Product = li.OriginalProduct,
    Vendors = li.CostingLineItemVendors,
    HasProviderAvailable = hasProviderAvailable
}

其余的,當然有通常的嫌疑人。 隨着數據庫量的增加,更好的索引可能變得更加重要。 檢查(和修復)數據庫碎片也會產生重大影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM