1

鉴于:

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 表达式

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

为什么会这样?

4

2 回答 2

7

它的发生是因为谓词的类型,应该是

Expression<Func<CV3Address, bool>>

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

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

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

于 2013-08-15T20:04:27.027 回答
3

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

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

您需要更改方法以获取表达式树:

Expression<Func<CV3Address, bool>>
于 2013-08-15T20:04:40.497 回答