2

请参阅下面的两个功能相同的查询,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 子句。我想避免从表 Line 中提取所有记录。我试图将 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()

不会工作

4

1 回答 1

4

您只需这样做:

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直接选择。

于 2012-08-13T19:17:45.883 回答