Linq to sql LINQ到SQL:重用lambda表达式

Linq to sql LINQ到SQL:重用lambda表达式,linq-to-sql,Linq To Sql,我偶然发现了一些奇怪的LINQ-to-SQL行为——有人能解释一下吗 我想定义一个lambda表达式并在LINQ语句中使用它。以下代码可以正常工作: [...] Func<Table1, bool> lambda = x => x.Id > 1000; var result = dataContext.Table1s.Where(lambda); [...] 但是,我不明白这一点:当我将lambda直接放入查询时,它可以正常工作: [...] var result =

我偶然发现了一些奇怪的LINQ-to-SQL行为——有人能解释一下吗

我想定义一个lambda表达式并在LINQ语句中使用它。以下代码可以正常工作:

[...]
Func<Table1, bool> lambda = x => x.Id > 1000;
var result = dataContext.Table1s.Where(lambda);
[...]
但是,我不明白这一点:当我将lambda直接放入查询时,它可以正常工作:

[...]
var result = dataContext.Table2s.Where(x => x.Table1s.Any(y => y.Id > 1000));
[...]
为什么


谢谢。

表1是否引用了相同的命名空间?在第一个示例中,您正在查询直接位于
dataContext
下的
Table1
对象,在第二个示例中,您正在查询作为
Table2
对象的属性的
Table1
对象,在最后一个示例中,您正在使用一个匿名函数来解决问题


我将查找作为
Table2
对象属性的
Table1
对象的类型,并将其与直接连接到
dataContext
Table1
对象进行比较。我猜它们是不同的,您的lambda表达式使用的是连接到
dataContext

的对象的类型。好的,这里的交易是:
dataContext。Table1s
的类型是
IQueryable
IQueryable
定义
Where
任何采用
表达式类型的谓词的
方法。
表达式
包装器非常重要,因为它允许linqtosql将lambda表达式转换为SQL并在数据库服务器上执行

但是,
IQueryable
还包括
IEnumerable
IEnumerable
还定义了
Where
任何
方法,但IEnumerable版本采用
Func
类型的谓词。因为这是一个已编译的函数而不是表达式,所以无法将其转换为SQL。因此,此代码

Func<Table1, bool> lambda = x => x.Id > 1000;
var result = dataContext.Table1s.Where(lambda);
此版本有两个lambda表达式。第二个表达式直接传递到
,其中
,是一个
表达式
,其中包含对
函数的引用。您不能将两者混用,您收到的错误消息告诉您,对
Any
的调用需要一个
表达式
,但您正在传入一个
Func

var result = dataContext.Table2s.Where(x => x.Table1s.Any(y => y.Id > 1000));
在这个版本中,您的内部lambda将自动转换为
表达式
,因为这是您希望代码通过LINQ转换为SQL的唯一选择。在其他情况下,您强制lambda成为
Func
,而不是
表达式
——在这种情况下,您不是,因此它可以工作

解决办法是什么?其实很简单:

Expression<Func<Table1, bool>> lambda = x => x.Id > 1000;
表达式lambda=x=>x.Id>1000;

尝试使用
var lamda=x=>x.Id>1000。我不知道这会有帮助,但它可能…@Alxandr-这实际上是不合法的。Lambda表达式可以编译为
Func
Expression
,在您的示例中,编译器将无法分辨您想要哪个表达式,并将抛出一个错误。谢谢。不幸的是,它无法编译,编译器错误是:参数2:无法从“System.Linq.Expressions.Expression”转换为“System.Func”。该错误消息似乎表明您正在对实现IEnumerable但不可IQueryable的对象调用
Where
Any
,因为这些版本需要Func,其中版本需要一个表达式。如果它不接受表达式,则对象可能不可IQueryable…它被定义为EntitySet,由SQLMetal/Visual Studio Designer为LINQ到SQL表关联生成。也许对你有帮助…谢谢你的链接,乔尔。它不能解决我的上述问题,但它非常有用,给了我一些新的想法:)
Func<Table1, bool> lambda = x => x.Id > 1000;
var result = dataContext.Table2s.Where(x => x.Table1s.Any(lambda));
var result = dataContext.Table2s.Where(x => x.Table1s.Any(y => y.Id > 1000));
Expression<Func<Table1, bool>> lambda = x => x.Id > 1000;