【发布时间】:2018-05-30 13:13:37
【问题描述】:
我正在尝试 combine two lambda expressions 使用 OR 子句构建一些东西,但它失败并显示以下异常消息:
从范围“”引用了“Foo”类型的变量“foo”,但未定义。
为什么,我该如何解决?
这是一个失败的代码示例,基于上面链接的问题的Marc Gravell's answer:
static Expression<Func<T, bool>> Or<T>(Expression<Func<T, bool>> a, Expression<Func<T, bool>> b)
=> Expression.Lambda<Func<T, bool>>(Expression.OrElse(a.Body, b.Body), b.Parameters);
static Expression<Func<Foo, bool>> BarMatches(Bar bar) => foo => foo.Bar.Value == bar.Value;
static Expression<Func<Foo, bool>> BazMatches(Baz baz) => foo => foo.Baz.Value == baz.Value;
// sample usage (see below): foos.Where(Or(MatchesBar(bar), MatchesBaz(baz)))
void Main()
{
var foos = new[]
{
new Foo
{
Bar = new Bar
{
Value = "bar"
},
Baz = new Baz
{
Value = "baz"
}
},
new Foo
{
Bar = new Bar
{
Value = "not matching"
},
Baz = new Baz
{
Value = "baz"
}
}
}.AsQueryable();
var bar = new Bar { Value = "bar" };
var baz = new Baz { Value = "baz" };
Console.WriteLine(foos.Where(Or(BarMatches(bar), BazMatches(baz))).Count());
}
// Define other methods and classes here
class Foo
{
public Bar Bar { get; set; }
public Baz Baz { get; set; }
}
class Bar
{
public string Value { get; set; }
}
class Baz
{
public string Value { get; set; }
}
【问题讨论】:
-
与您链接的相同解释了这一点。答案开始:“但问题是参数;你在 expr1 和 expr2 中使用相同的 ParameterExpression 吗?如果是这样,那就更容易了”。您没有使用相同的参数 - 因此此代码不适用于您的情况,您需要进一步阅读该答案。
-
@Evk,谢谢:我试图避免
Expression.Invoke,因为我担心 EF Linq 提供程序无法应对 - 结果证明它工作得很好。如果您想将其写为答案,我可以接受并为您提供一些代表:) -
如果您使用的是 EF Core,我会确保它确实将其转换为 SQL,而不仅仅是在内存中调用。但我认为这个问题的真正解决方案是表达式访问者方法,正如在那个答案中再次提到的那样:) 或者像 LinqKit 这样的第三方库,它们会为你做到这一点。
标签: c# linq lambda linq-expressions