【问题标题】:EF does not include where clauseEF 不包含 where 子句
【发布时间】:2012-06-08 14:14:42
【问题描述】:

我对 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 子句和 select(我尝试只选择一列)在枚举后执行。我想要它做的是使用 where 子句生成一个 SQL 查询并只选择一列。

我做错了什么?

【问题讨论】:

  • 只是提醒一下,o.Any() 吗? o.FirstOrDefault():null 是多余的。 o.FirstOrDefault() 如果找不到匹配项,将返回 null。
  • Table 到底是什么?
  • 我现在把空值放在那里,我实际上是在返回一些东西,但不想在这里发布它,无论如何它不会影响查询

标签: c# sql linq entity-framework


【解决方案1】:

由于您要创建IEnumerable&lt;string&gt; 类型的对象,EF 在第一行运行此查询。然后在内存集中执行Any()FirstOrDefault()。 如果您想“继续”编写 linq 语句并在最后运行查询;就用IQueryable&lt;T&gt;吧。

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;

【讨论】:

  • Any 和 FirstOrDefault 是正确的,但是 WHERE 应该在数据库上执行,而不是在内存中。
  • 谢谢!这解决了它。我从来不知道 IEnumerable 是这样工作的。 IQueryable 似乎在更多情况下可用。这是 linq 的懒惰的地方吗?
  • 事实上,如果您在可查询对象上编写 linq 语句,EF 以延迟执行方式工作。但是,当您将可查询对象转换为“实体”类型时,例如 IEnumerable,它只会执行查询。总而言之,EF 推迟执行,直到 IQueryable 对象被强制转换为“实体”类型。
【解决方案2】:
return table.FirstOrDefault(P => P.ITEMID == itemid && P.IMAGESIZE == size); 

我相信这就是您想要实现的目标。这将在您的 SQL 中为您提供 where 子句,并立即带回记录或 null。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-06
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多