2015-07-12 29 views
5

请看看这些行:Func键<t, bool> VS在C#拉姆达手动表达性能

1.在这种情况下,我键入声明直接方法

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键通用where子句

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子句是WHERE 1 = [Extent1].[Id]丢失,因此整个记录存储在内存中。你有什么想法为什么where子句不在SQL查询翻译?
我想在.Where()中使用Func<t, bool>,所以它是通用的,不需要为每个查询创建函数。
有没有什么办法可以使用.Where(Func<t, bool>)并且在sql查询中看到了翻译的where子句?

回答

9

如果你想在SQL要执行你的拉姆达,你需要把它作为一个表达式,而不是一个功能:

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

如果你想知道有什么区别(毕竟拉姆达本身看起来一样),看看this question

+0

这很简单,我想知道为什么我的应用程序太慢了...谢谢 – mhesabi

3

而不是

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

你应该当您使用Expression实体框架使用

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

能翻译为正确的SQL。另一方面,当您使用Func实体框架不知道如何将其转换为SQL,因此它正在使用内存中的处理。

3

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

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

相关问题