首页 > 解决方案 > Entity Framework Core——是否需要检查查询是否可以返回结果

问题描述

考虑以下代码片段:

 public async Task<List<MyModel>> GetAllForIds(IList<Guid> ids) 
 {
    // query the database for entities which have a field that matches one of the ids,
    // then map those entities to models and return.
 }

如果 id 列表为空,则显然查询不会返回任何内容,因此最好不要费心联系数据库。我的问题是 EF Core 是否足够聪明,可以自己解决这个问题。如果不是,并且如果可能有一个空的 id 列表,我应该将上面的内容更改为如下所示:

public async Task<List<MyModel>> GetAllForIds(IList<Guid> ids) 
{
    if (ids.Any()) 
    {
        // query the database for entities which have a field that matches one of the ids,
        // then map those entities to models and return.
    } 
    else 
    {
        return new List<MyModel>();
    }
}

标签: c#entity-framework-core

解决方案


如果您想在确定不会返回任何数据时防止数据库往返,您必须自己做。

EF core 甚至去掉了这方面的一些“聪明”。在“经典” EF6中,当执行类似...的查询时

Products.Where(p => false)

...检测到该Where语句的计算结果为false(即使这有点困难,并且在您的情况下也有一个空集合),并且它向数据库发送一个虚拟查询。就像是:

SELECT 
    CAST(NULL AS int) AS [C1], 
    CAST(NULL AS varchar(1)) AS [C2], 
    CAST(NULL AS int) AS [C3], 
    CAST(NULL AS decimal(18,2)) AS [C4], 
    CAST(NULL AS datetime2) AS [C5], 
    ...
    FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
    WHERE 1 = 0

所以数据库几乎不会注意到它。但它仍然是一个往返。我不知道为什么 EF6 会这样做,而它看起来很聪明,知道它可能会IQueryable立即返回一个空的。

EF-core停止发送这个虚拟查询。它确实检测到谓词的计算结果为false,但随后它只是生成如下查询:

SELECT [p].[Id], etc., etc.
FROM [Products] AS [p]
WHERE 0 = 1

我对此很满意。所有内置的智能都会带来在特定情况下过于智能的风险,这些情况在弹出之前被忽略。我要求 EF 执行查询,它确实执行了。很好很简单。


推荐阅读