使用Linq to Entities时,当我在使用书面LINQ语句创建的Linq对象上执行Where lamba表达式时,where子句不起作用。
这不起作用。查询执行,但结果未经过滤返回。
var myQuery = (from l in db.MyTable
select l).Where(r => availableStatusList.Contains(r.Status));
var myObj = myQuery.ToList();
这确实有效。查询执行,AND结果返回正确过滤。
test1(n)
据我了解,这两个都应该返回相同的结果。第一个没有听到Where子句的原因是什么?
答案 0 :(得分:7)
Where
子句在调用时不会创建新对象;它通过将集合包装在最终将运行的过滤器中,将过滤器应用于现有集合。但是,由于它是纯函数,因此需要将该过滤器的返回值返回到原始引用myQuery
,这就是第二个示例有效的原因...您已通过{{1}链接结果}子句回到Where()
。您返回过滤后的集合,使用myQuery
实现延迟查询。
在第一个示例中,您假设过滤器直接应用于集合,但这并不是ToList()
的工作方式,因为过滤器不会立即修改集合。函数被调用。相反,它仅应用将被应用的谓词,前提是它附加了"到原始LINQ
集合,然后使用Queryable
解析查询。
有时候将延迟执行视为一系列承诺更容易。
如果我给你一美元,你就有一美元。如果我拿25美分的税,我立即解决了我们的交易(查询)。
但是,如果我保证在星期二给你一美元,我已经退回ToList()
承诺。
从现在到星期二,可能会发生多个事件。我可以为税收(25美分),一根口香糖(25美分)或任何其他过滤器过滤器。
然而,我们的簿记系统有一个警告。我们无法在承诺总金额上调用Queryable<T>
(我们的.Taxes()
条款),并希望它能够更新。我们必须通过将过滤器返回到原始变量来记录我们的交易与承诺的金额,并使用我们承诺金额发生的交易更新它。
Where
周二,当你来收取你的付款时(通过在一系列链式承诺/过滤器上调用myQuery = myQuery.Where(condition);
),我会从承诺中扣除已经发生的事情,从而获得50美分的赔付。这推迟了在工作中的执行。
答案 1 :(得分:3)
更短的答案:
与字符串mutator函数类似,您需要将其分配回变量:
string sample = "text";
// this doesn't change sample
sample.ToUpper();
// this one does
sample = sample.ToUpper();
所以你需要的是:
myQuery = myQuery.Where(...)