Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架导致超时错误_C#_Sql Server_Linq_Entity Framework - Fatal编程技术网

C# 实体框架导致超时错误

C# 实体框架导致超时错误,c#,sql-server,linq,entity-framework,C#,Sql Server,Linq,Entity Framework,我正在处理以下实体框架查询。我知道这里发生了很多事情,但我希望有人能够发现这个问题 var lineItems = from li in Repository.Query<CostingLineItem>() let cid = (li.ParentCostingPackage != null) ? li.ParentCostingPackage.ParentCostingEvent.ProposalSecti

我正在处理以下实体框架查询。我知道这里发生了很多事情,但我希望有人能够发现这个问题

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
                };
有人能看到该代码是如何持续导致超时错误的吗


(注意:这段代码是一个运行了几年的大型应用程序的一部分。因此,我真的不认为这与连接字符串或类似的东西有任何关系。如果我做了上述更改,它将始终如一地工作。)

我认为这将给您带来更好的性能,但不确定它是否能解决问题:

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
}
来自Repository.Query()中的li
让cid=(li.ParentCostingPackage!=null)?
li.ParentCostingPackage.ParentCostingEvent.ProposalsSection.Proposal.Costing.Id:
li.ParentCostingEvent.ProposalSection.Proposal.Costing.Id
其中cid==costingId&&
li.OriginalProductId.HasValue&&
li.数量>0&&//无空检查
分类。包含(li.OriginalProduct.ClassificationEnumIndex)
让selectedChoiceId=(从li.OriginalPackageOption.CostingLineItems中的c开始)
orderby c.IsIncluded?-2:c.IsDefaultItem?-1:c.Id//无空检查
选择(int)c.OriginalPackageOptionChoiceId).FirstOrDefault()
哪里li.OriginalPackageOptionId.HasValue | | li.OriginalPackageOptionId==selectedChoiceId
让hasProviderAvailable=li.OriginalProductItem.ProductItemVendors.Any(
piv=>piv.ProductPricings.Any(pp=>pp.ProductItemVendor.CompanyId!=null | | pp.ProductItemVendor.HotelId!=null))
选择新的
{
LineItem=li,
ProductItem=li.OriginalProductItem,
产品=li.原始产品,
供应商=li.costinglineitemsvendors,
HasProviderAvailable=HasProviderAvailable
}

至于其他人,当然还有通常的嫌疑犯。随着数据库容量的增加,更好的索引可能变得更加重要。检查(并修复)数据库碎片也会产生重大影响。

它看起来与sql server相关,而不是EF问题。其他人建议更新统计数据。也可能是阻塞问题-您可以尝试读取未提交的数据。@VojtěchDohnal:我假设错误最终发生在SQL Server中。问题是,在SQL Server中,哪些行会导致此问题。我高度怀疑这是一个阻塞问题。阻塞问题通常取决于其他代码,并且不会像上面的代码那样一致。第一次查看时,我怀疑
selectedChoiceId
声明会导致从EF向SQL Server发送更复杂的子查询,因此自然删除它会执行得更快(因此不会超时)。我将附加探查器,捕获生成的SQL,并调查其估计的执行计划,以查看它会命中哪些索引以及如何移动。尝试移动
var choice=(从li.OriginalPackageOption.CostingLineItems orderby中的c开始)(c.isinclude??false)?-2:(c.IsDefaultItem??false)?-1:c.Id选择(int)c.OriginalPackageOptionChoiceId)。首先Ordefault():0
然后使用
let selectedChoiceId=choice
我认为子查询应该有问题。@Nilesh:将其移动到何处,为什么会有任何区别?
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
}