Where子句不适用于LINQ IQueryable查询

use*_*500 2 c# linq entity-framework

使用Linq to Entities时,当我在使用书面LINQ语句创建的Linq对象上执行Where lamba表达式时,where子句不起作用.

这不起作用.查询执行,但结果未经过滤返回.

var myQuery = (from l in db.MyTable
                     select l);
myQuery.Where(r => availableStatusList.Contains(r.Status));
var myObj = myQuery.ToList();  
Run Code Online (Sandbox Code Playgroud)

这确实有效.查询执行,AND结果返回正确过滤.

var myQuery = (from l in db.MyTable
                     select l).Where(r => availableStatusList.Contains(r.Status));
var myObj = myQuery.ToList();
Run Code Online (Sandbox Code Playgroud)

据我了解,这两个都应该返回相同的结果.第一个不听Where Where子句的原因是什么?

Ste*_*uel 9

更简短的答案:

类似于字符串修改器函数,您需要将其分配回变量:

string sample = "text";

// this doesn't change sample
sample.ToUpper();   

// this one does
sample = sample.ToUpper();
Run Code Online (Sandbox Code Playgroud)

所以你需要的是:

myQuery = myQuery.Where(...)
Run Code Online (Sandbox Code Playgroud)


Dav*_*d L 7

一个Where调用时子句不会创建新的对象; 它通过将集合包装在最终将运行的过滤器中,将过滤器应用于现有集合.但是,由于它是纯函数,因此需要将该过滤器的返回值返回到原始引用myQuery,这就是第二个示例有效的原因...您已通过该Where()子句将结果链接回myQuery.您将返回已过滤的集合,使用实现延迟查询ToList().

在第一个示例中,您假设过滤器直接应用于集合,但这LINQ不起作用,因为过滤器在调用函数时不会立即修改集合.相反,它仅应用将被应用的谓词,前提是它"附加"到原始Queryable集合并且您使用解析查询ToList().

有时候将延迟执行视为一系列承诺更容易.

如果我给你一美元,你就有一美元.如果我拿25美分的税,我立即解决了我们的交易(查询).

但是,如果我保证在星期二给你一美元,我已经Queryable<T> 答应了.

从现在到周二,可能会发生多个事件.我可以为税收(25美分),一根口香糖(25美分)或任何其他过滤器过滤器.

但是,我们的簿记系统有一个警告.我们不能只对所承诺的总额调用.Taxes()(我们的Where条款)并期望它更新.我们必须通过将过滤器返回到原始变量来记录我们的交易与承诺的金额,并根据我们承诺的金额进行更新.

myQuery = myQuery.Where(condition);
Run Code Online (Sandbox Code Playgroud)

周二,当你来收取你的付款时(通过ToList()一系列链式承诺/过滤器),我会从承诺的内容中扣除已经发生的事情,从而获得50美分的赔付.这是推迟执行的工作.