使用 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();
这确实有效。执行查询,并返回正确过滤的结果。
var myQuery = (from l in db.MyTable
select l).Where(r => availableStatusList.Contains(r.Status));
var myObj = myQuery.ToList();
据我所知,这两个应该返回相同的结果。第一个不听 Where 子句的任何原因?
最佳答案
A Where
子句在调用时不会创建新对象;它通过将集合包装在最终将运行的过滤器中来将过滤器应用于现有集合。但是,由于是纯函数,所以那个filter的返回值需要返回到原始引用myQuery
,这就是第二个示例起作用的原因...您已通过 Where()
链接了结果子句返回 myQuery
.您返回过滤后的集合,用 ToList()
实现延迟查询.
在第一个示例中,您假设过滤器直接应用于集合,但事实并非如此LINQ
有效,因为过滤器不会在调用函数时立即修改集合。相反,它只应用一个将被应用的谓词,前提是它“附加”到原始 Queryable
。集合,然后使用 ToList()
解决查询.
有时将延迟执行视为一系列 promise 会更容易。
如果我给你一美元,你就有一美元。如果我收取 25 美分的税款,我立即解决了我们的交易(查询)。
但是,如果我答应在星期二给你一美元,我已经退还了一个 Queryable<T>
promise 。
但是从现在到周二之间可能会发生多个事件。我可以链接一个税过滤器(25 美分)、一个口香糖过滤器(25 美分)或任何其他过滤器。
但是,我们的簿记系统有一个警告。我们不能只调用 .Taxes()
(我们的 Where
条款)关于总 promise 金额并期望它更新。我们必须记录我们的交易,方法是将过滤器返回到原始变量,并使用根据我们 promise 的金额发生的交易更新它。
myQuery = myQuery.Where(condition);
周二,当您来收款时(通过在一系列链式 promise /过滤器上调用 ToList()
),我从 promise 的内容中扣除已发生的内容,得到 50 美分的付款。这就是工作中的延迟执行。
关于c# - Where 子句不适用于 LINQ IQueryable 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36730649/