【问题标题】:Linq. How to use AsEnumerable within Linq (sql syntax) query? EF4.1林克。如何在 Linq(sql 语法)查询中使用 AsEnumerable? EF4.1
【发布时间】:2012-08-13 19:14:55
【问题描述】:

请参阅下面的两个功能相同的查询,sql 和 lambda 版本:

from a in Lines.AsEnumerable()
where a.LineId == SomeGuid
select a

-

Lines.AsEnumerable()
.Where(a => a.LineId == SomeGuid)
.Select(a => a)

这两个查询都会被翻译成没有 WHERE 语句的 SQL,比如

SELECT * FROM Line 

在 lambda 中,我可以方便地将 AsEnumerable 放在 Where 子句之后,生成的 SQL 将包含 WHERE 子句。所以,lambda 查询就像:

Lines
.Where(a => a.LineId == SomeGuid)
.AsEnumerable()
.Select(a => a)

生成的 SQL 是 SELECT * FROM Line WHERE LineId = @param

问题: 如何使用 Linq SQL 语法做到这一点?换句话说,我希望生成的 SQL 语句具有 WHERE 子句。我想避免从表行中提取所有记录。我尝试将 AsEnumerable 放在查询中的不同位置,但未能成功。

编辑:
在简单的语句中将 AsEnumerable 放在最后会起作用,但是如果您使用投影,则 EF 会抱怨(NotSupported Exception: Complex type can't beConstructed ...) 所以,

 (from a in Lines
    where a.LineId == SomeGuid
    select new Line
    {
        LineId = a.LineId
    }).AsEnumerable()

没用

【问题讨论】:

  • 你怎么知道 LINQ 查询没有 WHERE 子句?根据我使用 LINQ 的经验,您会得到完全相同的结果,只是它是 IQueryable,而不是 IEnumerable。使用扩展方法,只有在 .Where() 之后放置 .AsEnumerable() 才能获得 WHERE 子句。
  • 我在 LinqPad 中运行查询,它向我展示了生成的 SQL
  • 是的,那是我的问题。当我将使用 Linq SQL 语法时,我不知道如何将 AsEnumerable 放在 WHERE 子句之后。拉迪斯拉夫回答了这个问题。在这种情况下,似乎 lambda 语法会提供更易于阅读的代码。出于某种原因(我猜是因为它看起来类似于 T-SQL 语法)我倾向于坚持使用 Linq SQL 语法。

标签: linq lambda entity-framework-4.1 asenumerable


【解决方案1】:

您只需这样做:

var query (from a in context.Lines
           where a.LineId == SomeGuid
           select a).AsEnumerable();

但在大多数情况下,这不是必需的。它使您的查询可枚举,但不执行您的查询。只有在迭代时才会执行查询。

顺便说一句。 .Select(a => a) 在您的示例中是不需要的,因为它会自动发生。

编辑:

Linq-to-entities 禁止投影到映射类型,所以正如我提到的,你必须首先投影到匿名类型,调用 AsEnumerable 并投影到真正的映射类型。

var query =  (from a in Lines
              where a.LineId == SomeGuid
              select new {
                  LineId = a.LineId
              }).AsEnumerable()
              .Select(a => new Line { LineId = a.LineId });

在这种情况下你甚至不需要匿名类型,因为你可以直接选择a.LineId

【讨论】:

  • 如果我使用投影会怎样?例如下面的查询会抛出一个错误:(from a in context.Lines where a.LineId == SomeGuid select new Line { LineId = a.LineId }).AsEnumerable();
  • 与投影相同,直到您的投影包含一些 .NET 代码或尝试投影到映射类型(您的示例)。在这种情况下,您必须投影到匿名类型,调用AsEnumerable 并再次投影到您的真实类型。
  • 非常感谢。这是有道理的。
  • 我试过了。它有效......今天学到了一些新东西。 :-) 谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
  • 1970-01-01
  • 2015-09-16
  • 1970-01-01
相关资源
最近更新 更多