2012-06-04 87 views
1

我有EF小问题。我正在一张大桌子上进行查询,并且需要很长时间。我想我找到了原因,但找不到解决办法;EF不包括在哪里条款

我的LINQ查询看起来是这样的:

IEnumerable<string> o = (from P in Table where P.ITEMID == itemid && P.IMAGESIZE == size select P.PATH); 
return o.Any() ? o.FirstOrDefault() : null; 

我希望这产生具有where子句的SQL查询,但它实际上产生的是:

SELECT 
[Extent1].[ITEMID] AS [ITEMID], 
[Extent1]......... 
snap 10 columns 
FROM [dbo].[TABLE] AS [Extent1] 

where子句和选择(我尝试只选择一列)在枚举之后执行。我想要它做的是用where子句产生一个SQL查询并只选择一列。

我在做什么错?

+3

刚刚起来,o.Any()? o.FirstOrDefault():null是多余的。如果未找到匹配项,o.FirstOrDefault()将返回null。 –

+0

什么是“表”? –

+0

我现在把null放在那里,我实际上返回了一些东西,但不想在这里发布,它不影响查询 – reinder

回答

1

由于您正在创建IEnumerable<string>类型的对象,因此EF会在第一行中运行此查询。然后在内存集中执行Any()FirstOrDefault()。 如果您想“继续”编写linq语句并最终运行查询;只要去IQueryable<T>

IQueryable<string> o = (from P in Table where P.ITEMID == itemid && P.IMAGESIZE == size select P.PATH); 
return o.SingleOrDefault(); 

但是正如Ryan Bennett所建议的那样,它更易于使用;

return Table.Where(p => p.ITEMID == itemid && P.IMAGESIZE == size).SingleOrDefault().PATH; 
+0

对任何和FirstOrDefault都是真的,但是WHERE应该已经被执行了数据库,不在内存中。 –

+0

谢谢!这解决了它。我从来不知道IEnumerable以这种方式工作。在更多的情况下,IQueryable似乎是可以使用的。这是linq的懒惰进来的地方吗? – reinder

+0

实际上,如果您在可查询对象上编写linq语句,EF将以延迟执行方式工作。但是,当您将可查询对象转换为“固体”类型时,如IEnumerable,它只是执行查询。作为一个总结,EF推迟执行,直到IQueryable对象被转换为“实体”类型。 – daryal

0
return table.FirstOrDefault(P => P.ITEMID == itemid && P.IMAGESIZE == size); 

我相信这是你要完成的任务。这会在你的SQL中给你一个where子句,并立即返回记录或null。