假设我有这条线:
var eggs = db.Nests.Single(b => b.id = 20).Birds.FirstOrDefault().Eggs;
在我的探查器跟踪中,我看到正在执行多个命令:
SQL:BatchString
SELECT TOP (2)
[Extent1].[id]
...
FROM [dbo].[Nest] AS [Extent1]
WHERE 20 = [Extent1].[id]
SQL:BatchCompleted
RPC:Completed
exec sp_executesql N'SELECT
[Extent1].[Id] AS [Id],
...
FROM [dbo].[Bird] AS [Extent1]
WHERE [Extent1].[NesId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=20
RPC:Completed
exec sp_executesql N'SELECT
[Extent1].[Id] AS [Id],
...
FROM [dbo].[Egg] AS [Extent1]
WHERE [Extent1].[BirdId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=13
所有这些命令都是在同一个请求中执行的,还是每个命令都有往返?
此外,我能否确认这是编写上述内容的最有效方法:
var eggs = db.Nests.Include("Birds")
.Single(b => b.id = 20)
.Birds.Include("Eggs")
.FirstOrDefault()
.Eggs;
或者显式连接会更好吗?
最佳答案
首先,您在第一个示例中得到多个查询是完全正常的。除非您在第二个示例中使用 Include()
,否则访问任何导航属性都会生成一个新的 SQL 查询。
我不确定您的数据库架构是如何布局的,但假设 Birds
有一个名为 Nests
的 Id_Nest
外键,您可以将此查询重写为:
var eggs = db.Birds.Include("Eggs")
.First(x => x.Id_Nest == 20)
.Eggs
.ToList();
Include()
生成与显式 join
大致相同的代码,因此无需担心代码不同。至于往返,如果您指的是 Web 服务器和数据库之间的往返,那么是的,每个查询可能都有一次往返。不过,如果连接保持打开状态,这并不是什么大问题。但最好通过 join
或 Include()
一次性获得所需的一切,而不是点击 db 3 次。