1

我写了一些参数化 Lambda 查询

        //Method 1:
        Func<SalesOrderLineEntity, bool> func01 = (o => o.SOLNumber == "123456");
        var q01 = _context.SalesOrderLineEntities.Where(func01).ToList();
        //Got the result, but SQLServer Read All Records to memory before "where"

        //Method 2:
        Expression<Func<SalesOrderLineEntity, bool>> exp02 = (o => o.SOLNumber == "123456");
        var q02 = _context.SalesOrderLineEntities.Where(exp02).ToList();
        //Got the result,Exec "Where" in SQLServer

        //Method 3:
        Expression<Func<SalesOrderLineEntity, bool>> exp03 = (o => func01(o));
        var q03 = _context.SalesOrderLineEntities.Where(exp03.Compile()).ToList();
        //Same to Method 1,because Compile() result is Func<SalesOrderLineEntity, bool>

        //Method 4:
        var q04 = _context.SalesOrderLineEntities.Where(exp03).ToList();
        //Error:The LINQ expression node type 'Invoke' is not supported in LINQ to Entities

方法一和三:效率很低 方法四:错误

方法二:需要我通过 Lambda 构建一个表达式。我觉得这很困难,因为我会使用很多“if,else”。创建一个函数更容易。这样做的正确方法是什么?

4

2 回答 2

1

变化

方法 1:EF 读取数据库中的所有记录,因为您将 a 传递FuncWhere子句中,这不是正确的候选者:EF 无法从中提取所需的信息来构建查询,它只能在内存中使用该函数收藏。

方法 2:这是执行 EF 查询的正确方法,因为 EF 基于Expression tree. 当您编写时,它可能看起来与方法 1 相同,.Where但这是不同的。

IQueryable扩展方法使用表达式树,因此您可以(或 EF 可以)在运行时评估该信息。

方法 3:这与方法 1 基本相同,因为您编译表达式。这是您使用它们时的关键区别:表达式包含构建实际操作的信息,但这不是操作本身。您需要先编译它(或者例如,您可以基于它们构建 SQL 查询,这就是 EF 的工作方式)。

方法 4:EF 无法将您的func01()调用转换为任何 SQL 函数。它不能翻译任何类型的代码,因为它需要等效的 SQL 操作。您可以尝试使用通用方法,您会得到相同的结果,这与 Func 无关。

这里会发生什么?

如果我们简化底层过程,那么上面的答案可能会更清楚。

//Method 2:
Expression<Func<SalesOrderLineEntity, bool>> exp02 = (o => o.SOLNumber == "123456");
var q02 = _context.SalesOrderLineEntities.Where(exp02).ToList();
//Got the result,Exec "Where" in SQLServer

EF 可以读取以下内容(通过表达式):

  • 用户想要过滤Where
  • 这是一个表达式,让我们获取一些信息
  • 好吧,它需要SalesOrderLineEntity并且我有该类型的映射
  • 该表达式告诉该属性SOLNumber必须等于“123456”
  • 好的,我有一个映射,SOLNumber所以很好
  • 我可以将等号运算符转换为等效的 SQL 运算符
  • 一切正常,所以我们可以构建 SQL 查询

当然,你不能用一个Func例子来做这个,因为那个对象不包含这些信息。

于 2013-01-22T13:35:07.423 回答
0

Not sure if this is applicable but have you look at compiled queries: Compiled Queries (LINQ to Entities) which should result in a more efficient SQL statement

于 2014-08-07T17:00:18.093 回答