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)
我知道这是对的吗?那么它在另一个括号中的原因是什么?任何人有想法或任何人都可以解释为什么?非常感谢。
答案 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。