我的理解是以下代码:
IQueryable<Things> things = dataContext.Things.Take(10);
if (fromDate > new DateTime(1980, 1, 1))
things = things.Where(a => a.InsertedDate > fromDate);
if (toDate < defaultDate)
things = things.Where(a => a.InsertedDate < toDate);
应该导致查询(假设日期通过条件),如:
select top 10 [fields] from things
where inserteddate > '1/8/2010'
and inserteddate < '1/12/2010'
我已经介入并确认两个Where()语句已经设置,但是当我调用things.ToList()时,我得到了查询:
select top 10 [fields] from things
为什么这两个不会被合并到实际查询中?
答案 0 :(得分:4)
你的代码错了。对Queryable.Take
的调用应位于 end 以获取所需的查询:
IQueryable<Things> things = dataContext.Things;
if (fromDate > new DateTime(1980, 1, 1))
{
things = things.Where(a => a.InsertedDate > fromDate);
}
if (toDate < defaultDate)
{
things = things.Where(a => a.InsertedDate < toDate);
}
things = things.Take(10);
首先调用Take
时,它会从整个数据库中找到前十个元素,然后仅评估这10个项目的Where cause。结果通常包含少于十个元素。
理论上,您的错误代码可以作为单个数据库查询运行:
SELECT [fields]
FROM
(
SELECT TOP 10 [fields] FROM table1
) T1
WHERE inserteddate > '2010-01-08'
AND inserteddate < '2010-01-12'
似乎尚未实施此优化。但我怀疑像这样的查询经常被使用。
答案 1 :(得分:2)
尽管我的例子是将var实例化为IQueryable,但我的实际代码却是IEnumerable。 IEnumerable处理Where()显然不同,只有第一个表达式将针对DB执行,而所有后续表达式都在内存中执行,这与IQueryable不同。我责备扩展方法。