2

我的理解是以下代码:

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

为什么没有将两个 where 合并到实际运行的查询中?

4

2 回答 2

4

你的代码是错误的。调用Queryable.Take应该在最后得到你想要的查询:

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 原因。结果通常包含少于十个元素。

您的错误代码理论上可以作为单个数据库查询运行:

SELECT [fields]
FROM
(
   SELECT TOP 10 [fields] FROM table1
) T1
WHERE inserteddate > '2010-01-08'
AND inserteddate < '2010-01-12'

看来这个优化还没有实现。但我怀疑这样的查询是否经常使用。

于 2011-01-03T19:02:56.827 回答
2

Even though my example was instantiating the var as IQueryable, my actual code was doing so as IEnumerable. IEnumerable handles Where() differently apparently such that only the first expression will get executed against the DB and all subsequent ones do so in memory unlike IQueryable. I blame extension methods.

于 2011-01-04T18:16:00.293 回答