关于c#:使用Func和Expression Func运行查询之间的区别

diffrence between running query with Func and Expression Func

本问题已经有最佳答案,请猛点这里访问。

我一直在网上搜索func和expression func的区别,不知怎么的我明白了,第一个只是一个函数获取数据,然后在内存中应用函数,第二个是将它转换成SQL,然后在数据库中运行它,在我运行这两个查询之后:

1
2
3
4
5
6
7
8
9
10
11
 public IEnumerable<T> SelectAll(Expression< Func<T, bool>> predicate)
    {        
        return table.Where(predicate).ToList();
    }

     public IEnumerable<T> SelectAll(Func<T, bool> predicate)
    {

        return table.Where(predicate).ToList();

    }

我将断点设置为返回,第一个断点返回12行,第二个断点返回1200行,谓词为:

1
s=>s.id="12345"

第二个,在得到数据后应用谓词,我的问题是,在处理数据库时,我们通常应该使用func表达式?


Func是委托,Expression>是表达式。

表达式是一种抽象。

Expression可以编译成Func

1
2
3
Expression<Func<int, int>> expr = a => a + 1;
Func<int,int> func = expr.Compile();
var res = func(1); // (1+1) = 2

所以把表达式看作是表示表达式的树。

这棵树是抽象的,你可以用它做很多事情。

那么,当涉及到SQL时,我们如何利用这种行为呢?

您可以创建某人(实体框架)将转换为SQL的表达式。

所以当你有这样的表达:

1
users.Where(u => u.Name.StartsWith("a"));

它可以翻译成SQL,比如:

1
select * from Users where Name like 'a%'

因为有人编写了将表达式转换为SQL的代码,所以它支持许多方法,但不支持所有方法。因此,有时它会告诉您,它不能将您的方法转换为SQL,您必须提供一个Expression>,或者在SQL运行后运行该方法(使用linq to对象)。

底线是,在大多数情况下,您更喜欢使用表达式而不是iqueryables,并使用将在数据库上运行的过滤器创建SQL查询,而不是获取大量的数据库条目并在代码中过滤它们。


my question is,we usualy should use the expression func when we deal with DB?

是的,因为您希望向SQL Server提供尽可能多的信息,以便它能够优化数据库访问,并且希望最小化从SQL Server返回的数据(删除所有不必要的数据,并聚合SQL Server可以轻松聚合的数据),因为要将数据从SQL Server移动到.NET mach甚至是"工作"。

显然,如果在SQL中很难执行某些操作(如字符串操作),那么将其移动到.NET是可以接受的。

请注意,使用LINQ,您对结果查询没有很好的控制,很容易成为"多级野兽",也不能真正确定查询的哪一部分将在SQL Server上执行,哪一部分将在本地执行(例如,ef core经常在本地执行group by),也不能访问SQL的许多高级功能(全部例如分区方法)。