Func运行查询与Expression Func之间的区别

时间:2018-07-26 08:07:59

标签: c# theory func

我一直在互联网上搜索以找出Func和Expression Func之间的区别,以某种方式我明白了,第一个只是一个函数获取数据,然后将其应用到内存中,而第二个,将其翻译为sql并在数据库中运行它,然后运行以下两个查询:

 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行,谓词为:

s=>s.id="12345"

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

2 个答案:

答案 0 :(得分:1)

  

我的问题是,在处理数据库时,通常应该使用func表达式吗?

是的,因为您希望向SQL服务器提供尽可能多的信息,以便它可以优化数据库访问,并且您希望最小化从SQL Server返回的数据(删除所有不必要的数据,并对数据进行汇总可以很容易地由SQL Server聚合),因为将数据从SQL Server移至.NET计算机甚至是“工作”。

很显然,如果在SQL中很难执行某些操作(例如字符串操作),则可以将其移动到.NET。

请注意,使用LINQ时,您对结果查询没有很好的控制,它很容易变成“多级野兽”,也无法真正确定查询的哪一部分将在SQL Server上执行以及哪一部分将在本地执行(例如,EF Core通常在本地执行GROUP BY),也无法访问SQL的许多高级功能(例如,所有分区方法)。

答案 1 :(得分:1)

Func<T>是委托,而Expression<Func<T>>是表达式。

表达式是一种抽象。

Expression<T>可以编译成Func<T>

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

因此,将表达式视为代表表达式的树。

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

那么在SQL方面,我们如何利用这种行为?

您可以创建一个表达式,供某人(实体框架)转换为SQL。

因此,当您有类似这样的表达式时:

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

它可以转换为SQL,例如:

select * from Users where Name like 'a%'

由于有人编写了将表达式转换为sql的代码,因此它支持多种方法,但不是全部。因此,有时它会告诉您它无法将您的方法转换为SQL,因此您必须提供Expression<Func<T>>或在SQL运行(使用Linq to Objects)后运行该方法。

最重要的是,在大多数情况下,您宁愿使用Expressions而不是IQueryables并使用将在数据库上运行的过滤器来创建SQL查询,而不是获取大量数据库条目并将其过滤在代码中。