繁体   English   中英

使用Func <>而不是lambda时,超时已过期

[英]Timeout expired when using a Func<> instead of a lambda

鉴于:

public EntityAddress ReadSingle(Func<EntityAddress, bool> predicate)
{
    //var result = Context.CV3Address.FirstOrDefault(a => a.GUID == 1100222);
    var result = Context.CV3Address.FirstOrDefault(predicate);
    return result;
}

FirstOrDefault(a => a.GUID == 1100222); 立即返回结果。

FirstOrDefault(predicate); 导致超时异常。 注意谓词= lambda表达式

我的怀疑是,后一种方法试图拉低所有记录,而这种记录不会在如此大的表中发生。

为什么会这样?

发生这种情况的原因是谓词的类型,而应改为

Expression<Func<CV3Address, bool>>

如果谓词是一个表达式树(如上所述),并且Context.CV3AddressIQueryable<CV3Address>则EF可以将表达式树转换为SQL,并直接从数据库中获取结果。

另一方面,如果谓词是Func<CV3Address, bool> (委托;指向已编译代码的指针),则无法将其转换为SQL。 因此,LINQ没有其他选择可将您的存储库视为IEnumerable<CV3Address> ,这是可以在内存中过滤的序列。 这具有需要从数据库中提取所有记录以对其进行过滤的副作用。

如果对谓词进行硬编码,则编译器可以将其视为表达式树或委托,并且由于Context.CV3Address的类型,因此会将其视为表达式树。

FirstOrDefault(a => a.GUID == 1100222)创建一个表达式树,该树使用LINQ to Entities在数据库服务器上运行查询。

FirstOrDefault(predicate)下载整个表并在本地运行过滤器。

您需要更改方法以采用表达式树:

Expression<Func<CV3Address, bool>>

暂无
暂无

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

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