Linq to sql LINQ到SQL:重用lambda表达式
我偶然发现了一些奇怪的LINQ-to-SQL行为——有人能解释一下吗 我想定义一个lambda表达式并在LINQ语句中使用它。以下代码可以正常工作: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 =
[...]
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;