使用 Func 和 Expression Func 的 运行 查询之间的差异

diffrence between running query with Func and Expression 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();

    }

我把断点放在 return 上,第一个 return 12 行,第二个 return 1200 行,谓词是:

s=>s.id="12345"

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

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

是的,因为您想向 SQL 服务器提供尽可能多的信息,以便它可以优化数据库访问,并且您希望最大限度地减少从 SQL 服务器返回的数据(删除所有不必要的数据,并聚合 SQL 服务器可以轻松聚合的数据),因为将数据从 SQL 服务器移动到 .NET 机器甚至是 "work"。

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

请注意,使用 LINQ,您无法很好地控制结果查询,它很容易变成 "multi-level-beast",您也无法真正确定查询的哪一部分将在 SQL服务器,哪部分会在本地执行(例如EF Core经常在本地执行GROUP BY),也不能访问SQL的许多高级功能(例如所有分区方法)。

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 时,我们如何才能利用这种行为?

您可以创建某人 (Entity Framework) 将翻译成 SQL.

的表达式

所以当你有这样的表达式时:

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

它可以翻译成 SQL 如:

select * from Users where Name like 'a%'

自从有人编写了将表达式翻译成 sql 的代码后,它支持许多方法,但不是全部。因此有时它会告诉您它无法将您的方法转换为 SQL 并且您必须提供 Expression<Func<T>> 或 运行 SQL [=54= 之后的方法]s(使用 Linq to Objects)。

最重要的是,在大多数情况下,您更愿意使用表达式而不是 IQueryables 并创建 SQL 带有过滤器的查询,这些过滤器将 运行 在数据库上而不是获取大量的数据库条目和过滤他们在你的代码中。