将谓词作为参数传递给Where 子句时,EF SQL 发生了变化

2024-04-28

EF 正在为下面列出的两个相似语句生成不同的 SQL

var test = dbcontext.Persons.GetAll()
                            .Where(c => c.PersonID == 2)
                            .Select(c => c.PersonName)
                            .FirstOrDefault();`

生成的SQL:

SELECT 
    [Limit1].[PersonName ] AS [PersonName ]
FROM 
    (SELECT TOP (1)
         [Extent1].[PersonName ] AS [PersonName ]
     FROM 
         [dbo].[ApplicationRequest] AS [Extent1]
     WHERE 
         [Extent1].[PersonID ] = @p__linq__0) AS [Limit1]',N'@p__linq__0 uniqueidentifier',@p__linq__0= "2"

我在多个不同的地方使用上述语句Where健康)状况;为了将逻辑整合到一个地方,我将条件作为参数传递

Public Void PassPredicate(Func<ApplicationRequest, bool> ReqFunc)
{
    var test = dbcontext.Persons.GetAll()
                                .Where(ReqFunc)
                                .Select(c => c.PersonName)
                                .FirstOrDefault();
}

我将该函数称为

PassPredicate(c => c.PersonID == 2);

生成的SQL:

SELECT 
    [Extent1].[PersonID] AS [PersonID], 
    [Extent1].[PersonName ] AS [PersonName ], 
    [Extent1].[DOB] AS [Dob], 
    [Extent1].[Height] AS [Height],
    [Extent1].[BirthCity] AS [BirthCity], 
    [Extent1].[Country] AS [Country],
FROM 
    [dbo].[Person] AS [Extent1]

如果您查看第二个 SQL,您会发现它非常令人震惊:它正在提取所有信息(列和行)。它没有 where 子句和选择所有列。

从数据库返回结果后应用 where 条件。

第二条语句中的唯一区别是我将条件作为参数传递,而不是在 where 子句中包含条件。

谁能解释为什么会有这样的差异?


Since ReqFunc类型是Func<ApplicationRequest, bool>你正在使用Enumerable扩展名,所以你的代码(Where, Select, FirstOrDefault) 将在内存中执行。

要解决这个问题,只需更改ReqFunc to Expression<Func<ApplicationRequest, bool>> to use Queryable扩展名:

Public Void PassPredicate(Expression<Func<ApplicationRequest, bool>> ReqFunc)
{
    var test = dbcontext.Persons.GetAll().Where(ReqFunc).Select(c => c.PersonName).FirstOrDefault();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将谓词作为参数传递给Where 子句时,EF SQL 发生了变化 的相关文章

随机推荐