使用Func<>;而不是lambda

本文关键字:lambda gt Func lt 使用 | 更新日期: 2023-09-27 18:27:56

给定:

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

CCD_ 1立即返回结果。

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

我怀疑后一种方法试图删除所有记录,这在这么大的表中是不会发生的。

为什么会发生这种情况?

使用Func<>;而不是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在DB服务器上运行查询。

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

你需要改变你的方法来获取一个表达式树:

Expression<Func<CV3Address, bool>>