简体   繁体   English

Func <t,bool> vs C#lambda中的手动表达性能

[英]Func<t, bool> vs Manually expression performance in C# lambda

Please take a look at these lines: 请看看这些线:

1. in this case I type where statement directly in method 1.在这种情况下,我直接在方法中键入where语句

public List<User> GetUsers()
{
    return _entity.Where(x => x.Id == 1).ToList();
}

Executed sql query is: 执行的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. in this case I used Func for generic where clause 2.在这种情况下,我使用Func for generic where子句

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

Executed sql query is: 执行的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]

as you can see, in case 2 where clause which is WHERE 1 = [Extent1].[Id] is missing and therefore whole records are stored in memory. 正如您所看到的,在情况2中,where子句是WHERE 1 = [Extent1].[Id]丢失,因此整个记录存储在内存中。 do you have any idea why where clause is not translated in sql query? 你知道为什么where子句没有在sql查询中翻译?
I want to use Func<t, bool> in .Where() so it would be generic and no need to create functions for each query. 我想在.Where()使用Func<t, bool> ,因此它是通用的,不需要为每个查询创建函数。
is there any way to use .Where(Func<t, bool>) and also see the translated where clause in sql query? 有没有办法使用.Where(Func<t, bool>)并且还可以在sql查询中看到翻译的where子句?

If you want your lambda to be executed in SQL, you need to pass it as an Expression, not a Function: 如果希望lambda在SQL中执行,则需要将其作为Expression传递,而不是函数:

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

If you wonder what the difference is (after all, the lambda itself looks the same), take a look at this question . 如果你想知道差异是什么(毕竟,lambda本身看起来一样),看看这个问题

Instead of 代替

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

you should be using 你应该使用

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

When you are using Expression Entity Framework is able to translate it to SQL correctly. 当您使用Expression Entity Framework时,能够正确地将其转换为SQL。 On the other hand when you are using Func Entity framework doesn't know how to translate that to SQL so it is using in-memory processing. 另一方面,当您使用Func Entity框架时,不知道如何将其转换为SQL,因此它使用内存中处理。

That is because in this two cases compiled code contains call to two different extension methods: Queryable.Where and Enumerable.Where respectively. 这是因为在这两种情况下,编译代码包含对两种不同扩展方法的调用: Queryable.WhereEnumerable.Where Queryable class contains extension methods for processing data from different data sources, including external sources whereas Enumerable contains extension methods for in-memory objects processing. Queryable类包含用于处理来自不同数据源(包括外部源)的数据的扩展方法,而Enumerable包含用于内存中对象处理的扩展方法。 Queryable version of Where accept Expression rather than Func . Queryable版本Where接受Expression ,而不是Func

Lamda expression can be implicitly converted to both Expression and Func , so as other answers pointed out you just need to accept an Expression instance as your function argument. Lamda表达式可以隐式转换为ExpressionFunc ,因此其他答案指出您只需要接受一个Expression实例作为函数参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM