LINQ-to-SQL 是否支持组合查询?
作为一名不懂 C# 的程序员,我对 LINQ 查询的评估语义很好奇,如下所示:
var people = from p in Person
where p.age < 18
select p
var otherPeople = from p in people
where p.firstName equals "Daniel"
select p
假设 Person
是一个定义 age
的 ADO 实体和 firstName
字段,从数据库的角度来看这会做什么? 具体来说,是否会运行 people
查询来生成内存中的结构,然后由 otherPeople
查询来查询该结构? 或者 otherPeople
的构造是否只是从 people
中提取有关查询的数据,然后生成一个新的数据库对等查询? 那么,如果我迭代这两个查询,将执行多少条 SQL 语句?
Speaking as a non-C# savvy programmer, I'm curious as to the evaluation semantics of LINQ queries like the following:
var people = from p in Person
where p.age < 18
select p
var otherPeople = from p in people
where p.firstName equals "Daniel"
select p
Assuming that Person
is an ADO entity which defines the age
and firstName
fields, what would this do from a database standpoint? Specifically, would the people
query be run to produce an in-memory structure, which would then be queried by the otherPeople
query? Or would the construction of otherPeople
merely pull the data regarding the query from people
and then produce a new database-peered query? So, if I iterated over both of these queries, how many SQL statements would be executed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
people
和otherPeople
包含IQueryable
类型的对象。如果您分别对两者进行迭代,它将运行两个查询。
如果您仅迭代
otherPeople
,它将运行预期的查询,并带有两个 where 子句。如果您对
people
执行.ToList()
并在第二个查询中使用返回的List
而不是 people,则它会变成 LINQ- to-Objects 并且不执行 SQL。这种行为称为延迟执行。 这意味着在需要之前不会执行任何查询。 在执行之前,它们只是表达式树,可以对其进行操作以制定最终查询。
people
andotherPeople
contain objects of typeIQueryable<Person>
.If you iterate over both, separatly, it will run two queries.
If you only iterate over
otherPeople
, it will run the expected query, with two where clauses.If you do
.ToList()
onpeople
and use the returnedList<Person>
in the second query instead of people, it becomes LINQ-to-Objects and no SQL is executed.This behavior is referred to as deferred execution. Meaning no query is done until it is needed. Before execution they are just expression trees that get manipulated to formulate the final query.
当您尝试访问最终结果时,这两个查询都会执行。 您可以尝试查看从 DataContext 对象属性生成的原始 SQL。
Both these queries will be executes when you'll try to access final results. You can try to view original SQL generated from DataContext object properties.
是的,生成的查询已组成。 它包括完整的 where 子句。 打开 SQL 分析并亲自尝试一下。
Linq 通过表达式树来完成此操作。 第一个 linq 语句生成一个表达式树; 它不执行查询。 第二个 linq 语句基于第一个语句创建的表达式树构建。 该语句仅在枚举结果集合时执行。
Yes, the resulting query is composed. It includes the full where clause. Turn on SQL profiling and try it to see for yourself.
Linq does this through expression trees. The first linq statement produces an expression tree; it doesn't execute the query. The second linq statement builds on the expression tree created by the first. The statement is only executed when you enumerate the resulting collection.
转换为:
其中 @p0 作为 18 发送
转换为:
其中 @p0 作为“Daniel”发送
转换为:
其中 @p0 为 18,@p1 为“Daniel”
如有疑问,请调用您的 ToString() IQueryable 或为 DataContext 的 Log 属性提供 TextWriter。
Translates to:
where @p0 gets sent through as 18
Translates to:
where @p0 gets sent through as "Daniel"
Translates to:
where @p0 is 18, @p1 is "Daniel"
When in doubt, call the ToString() on your IQueryable or give a TextWriter to the DataContext's Log property.
它们是可组合的。 这是可能的,因为 LINQ 查询实际上是表达式(代码即数据),LINQ-to-SQL 等 LINQ 提供程序可以评估并生成相应的 SQL。
由于 LINQ 查询是惰性计算的(例如,在迭代元素之前不会执行),因此您显示的代码实际上不会接触数据库。 直到您迭代 otherPeople 或 people 时,SQL 才会生成并执行。
They are composable. This is possible because LINQ queries are actually expressions (code as data), which LINQ providers like LINQ-to-SQL can evaluate and generate corresponding SQL.
Because LINQ queries are lazily evaluated (e.g. won't get executed until you iterate over the elements), the code you showed won't actually touch the database. Not until you iterate over otherPeople or people will SQL get generated and executed.