为什么"选择"方法语法在另一个括号中?

时间:2016-08-31 08:45:34

标签: linq lambda

var sample = db.Database.OrderByDescending(x => x.RecordId).Select(y => y.RecordId).FirstOrDefault();

我不知道我的头衔是correct / right。只想问为什么这个查询选择是在另一个( )?至于示例.Select(y => y.RecordId),不像我使用的查询

var sample = (from s in db.Databse where s.RecordId == id select s)我知道这是对的吗?那么它在另一个括号中的原因是什么?任何人有想法或任何人都可以解释为什么?非常感谢。

1 个答案:

答案 0 :(得分:3)

在您的第一个示例中,您使用“常规”C#语法来调用一堆扩展方法:

var sample = db.Database
               .OrderByDescending(x => x.RecordId)
               .Select(y => y.RecordId)
               .FirstOrDefault();

(它们恰好是扩展方法,但当然它们不一定是...)

您使用lambda表达式来表达您希望如何执行排序和投影,并且编译器将这些表达式转换为表达式树(假设这是EF或类似的;它将是LINQ to Objects的委托)。

第二个示例是查询表达式,尽管它实际上与第一个示例不匹配。与原始查询对应的查询表达式为:

var sample = (from x in db.Database
              orderby x.RecordId descending
              select x.RecordId)
             .FirstOrDefault();

查询表达式是非常多的语法糖。编译器有效地将它们转换为第一种形式,然后编译它。在from子句(本例中为x)中声明的范围变量用作lambda表达式的参数名称,因此select x.RecordId变为{{1 }}

连接和多个.Select(x => x.RecordId)子句使事情变得复杂一些,因为编译器引入了透明标识符,允许您处理范围内的所有范围变量,甚至虽然你真的只有一个参数。例如,如果你有:

from

将被翻译成等效的

var query = from person in people
            from job in person.Jobs
            order by person.Name
            select new { Person = person, Job = job };

请注意编译器如何引入匿名类型以将var query = people.SelectMany(person => person.Jobs, (person, job) => new { person, job } ) .OrderBy(t => t.person.Name) .Select(t => new { Person = t.person, Job = t.job }); person范围变量组合到单个对象中,稍后将使用该对象。

基本上,查询表达式语法使LINQ更容易使用 - 但它只是对其他C#代码的翻译,并且整齐地包含在C#规范的单个部分中。 (C#5规范第7.16.2节)

有关从查询表达式到“常规”C#的精确转换的详细信息,请参阅我的Edulinq blog post on query expressions