如何为表达式添加另一个条件?

Mos*_*ndi 10 c# linq

我有一个这样的表达式:

Expression<Func<int, bool>> exp = i => i<15 && i>10;
Run Code Online (Sandbox Code Playgroud)

我想exp在这一行之后添加一个条件.我怎样才能做到这一点?

Bar*_*zKP 16

只需这个:

Expression<Func<int, bool>> exp = i => i < 15 && i > 10;
var compiled = exp.Compile();
exp = i => compiled(i) && i % 2 == 0;  //example additional condition
Run Code Online (Sandbox Code Playgroud)

请注意,你不能这样做:

exp = i => exp.Compile()(i) && i % 2 == 0; //example additional condition

因为exp将通过引用添加到闭包中,因此调用它将导致a StackOverflowException.

  • 如果您使用Linq-to-sql(如EntityFramework),这将不起作用 (5认同)
  • @FindOutIslamNow 任何已编译的 lambda 都不会与 SQL 包装器一起使用,因为它们无法将已编译的表达式解析为 SQL。在这种情况下,您可以将后续的 `.Where` 子句附加到延迟的 `IQueryable` 对象 - 比这简单得多。 (2认同)

Geo*_*org 6

你有两个选择。第一个是 BartoszKP 的版本,将第一个表达式黑箱并在之后使用它。然而,虽然它有很好的语法支持,但这也意味着像实体框架这样的系统不能真正使用这个表达式,因为它是黑箱的。如果在数据库查询中使用此表达式,则 EF 无法在服务器上检查此谓词,但必须将所有数据检索到客户端(如果它起作用)。

因此,如果您想使用表达式(例如,用于数据库查询),您必须使用 Expression API,即

Expression<Func<int, bool>> exp = i => i<15 && i>10;
exp = Expression.Lambda<Func<int, bool>>(Expression.AndAlso(exp.Body, ...), exp.Parameters[0]);
Run Code Online (Sandbox Code Playgroud)

三个点表示要作为第二部分插入的表达式。您可以使用编译器创建的另一个表达式,但您必须替换参数。