sql server - Funcvs在c# lambda中手动表达性能

本文关键字:lambda 性能 vs Func server bool sql | 更新日期: 2023-09-27 18:02:14

请看这些行:

1。在本例中,我直接在方法

中键入where语句
public List<User> GetUsers()
{
    return _entity.Where(x => x.Id == 1).ToList();
}

执行的sql查询是:

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Username] AS [Username], 
    [Extent1].[Password] AS [Password], 
    [Extent1].[Email] AS [Email],
    [Extent2].[Id] AS [Id1]
    FROM  [dbo].[Account_Users] AS [Extent1]
    LEFT OUTER JOIN [dbo].[Account_Profiles] AS [Extent2] ON [Extent1].[Id] = [Extent2].[UserId]
    WHERE 1 = [Extent1].[Id]

2。在本例中,我使用Func作为泛型,其中子句

public List<User> GetUsers(Func<User, bool> where)
{
    return _entity.Where(where).ToList();
}
var users = _acc.GetUsers(x => x.Id == 1);

执行的sql查询是:

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Username] AS [Username], 
    [Extent1].[Password] AS [Password], 
    [Extent1].[Email] AS [Email], 
    [Extent2].[Id] AS [Id1]
    FROM  [dbo].[Account_Users] AS [Extent1]
    LEFT OUTER JOIN [dbo].[Account_Profiles] AS [Extent2] ON [Extent1].[Id] = [Extent2].[UserId]

,如你所见,在情况2中,WHERE 1 = [Extent1].[Id]子句缺失,因此整个记录存储在内存中。你知道为什么哪里的子句在SQL查询中不翻译吗?
我想在.Where()中使用Func<t, bool>,因此它将是通用的,不需要为每个查询创建函数。
是否有任何方法使用.Where(Func<t, bool>),也看到sql查询中翻译的where子句?

sql server - Func<t, bool>vs在c# lambda中手动表达性能

如果您希望lambda在SQL中执行,则需要将其作为表达式传递,而不是函数:

public List<User> GetUsers(Expression<Func<User, bool>> where)
{
    return _entity.Where(where).ToList();
}
var users = _acc.GetUsers(x => x.Id == 1);

如果您想知道它们之间的区别是什么(毕竟,lambda本身看起来是一样的),请看看这个问题。

代替

public List<User> GetUsers(Func<User, bool> where)

你应该使用

public List<User> GetUsers(Expression<Func<User, bool>> where)

当你使用Expression实体框架能够正确地将其转换为SQL。另一方面,当你使用Func实体框架不知道如何将其转换为SQL,所以它是使用内存处理。

这是因为在这两种情况下,编译后的代码分别包含对两个不同扩展方法的调用:Queryable.WhereEnumerable.WhereQueryable类包含用于处理来自不同数据源(包括外部数据源)的数据的扩展方法,而Enumerable类包含用于处理内存对象的扩展方法。WhereQueryable版本接受Expression而不是Func

lambda表达式可以隐式地转换为ExpressionFunc,因此,正如其他答案所指出的,您只需要接受Expression实例作为您的函数参数。