linq to sql multiple Where()语句没有创建单个表达式

时间:2011-01-03 19:01:07

标签: linq linq-to-sql expression linq-expressions

我的理解是以下代码:

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

为什么这两个不会被合并到实际查询中?

2 个答案:

答案 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不同。我责备扩展方法。