LINQ-to-SQL 是否支持组合查询?

发布于 2024-07-05 16:39:35 字数 580 浏览 3 评论 0原文

作为一名不懂 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

寻梦旅人 2024-07-12 16:39:35

peopleotherPeople 包含 IQueryable 类型的对象。

如果您分别对两者进行迭代,它将运行两个查询。
如果您仅迭代 otherPeople,它将运行预期的查询,并带有两个 where 子句。

如果您对 people 执行 .ToList() 并在第二个查询中使用返回的 List 而不是 people,则它会变成 LINQ- to-Objects 并且不执行 SQL。

这种行为称为延迟执行。 这意味着在需要之前不会执行任何查询。 在执行之前,它们只是表达式树,可以对其进行操作以制定最终查询。

people and otherPeople contain objects of type IQueryable<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() on people and use the returned List<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.

彡翼 2024-07-12 16:39:35

当您尝试访问最终结果时,这两个查询都会执行。 您可以尝试查看从 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.

浮华 2024-07-12 16:39:35

是的,生成的查询已组成。 它包括完整的 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.

北城挽邺 2024-07-12 16:39:35
var people = from p in Person
             where p.age < 18
             select p

转换为:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0]
WHERE [t0].[Age] < @p0

其中 @p0 作为 18 发送

var otherPeople = from p in people
                  where p.firstName equals "Daniel"
                  select p

转换为:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0]
WHERE [t0].[FirstName] = @p0

其中 @p0 作为“Daniel”发送

var morePeople = from p1 in people
                 from p2 in otherPeople
                 where p1.PersonId == p2.PersonId
                 select p1;

转换为:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0], [dbo].[Person] AS [t1]
WHERE ([t0].[PersonId] = [t1].[PersonId]) AND ([t0].[Age] < @p0) AND ([t1].[FirstName] = @p1)

其中 @p0 为 18,@p1 为“Daniel”

如有疑问,请调用您的 ToString() IQueryable 或为 DataContext 的 Log 属性提供 TextWriter。

var people = from p in Person
             where p.age < 18
             select p

Translates to:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0]
WHERE [t0].[Age] < @p0

where @p0 gets sent through as 18

var otherPeople = from p in people
                  where p.firstName equals "Daniel"
                  select p

Translates to:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0]
WHERE [t0].[FirstName] = @p0

where @p0 gets sent through as "Daniel"

var morePeople = from p1 in people
                 from p2 in otherPeople
                 where p1.PersonId == p2.PersonId
                 select p1;

Translates to:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0], [dbo].[Person] AS [t1]
WHERE ([t0].[PersonId] = [t1].[PersonId]) AND ([t0].[Age] < @p0) AND ([t1].[FirstName] = @p1)

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.

治碍 2024-07-12 16:39:35

它们是可组合的。 这是可能的,因为 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文