我有这个LINQ语句,
var carriageways = from carriageway in dataModelCurrentEntities.Carriageway
where carriageway.RoadId == roadId && carriageway.DistanceBreak == false
orderby carriageway.CarriagewayStartInMetre
select new CarriagewaySummary
{
StartMetres = carriageway.CarriagewayStartInMetre,
EndMetres = carriageway.CarriagewayEndInMetre
};
它以这种形式生成SQL(LINQ to entities),
SELECT
Project1.field1 AS field1
Project1.field2 AS field2
FROM ( SELECT
Extent1.field1 AS field1,
Extent1.field2 AS field2
FROM table AS Extent1
WHERE blah
) AS Project1
ORDER BY blah ASC
这是什么原因?我原本以为这样就足够了,
SELECT
fields
FROM table as Project1
WHERE blah
ORDER BY blah ASC
我记得LINQ to SQL倾向于生成更简单的SQL。
我已经查看了更复杂的连接等示例,LINQ to实体似乎生成了更复杂的SQL。
更新
这很有趣,因为我试图测试你在说什么,我遇到了这个LINQ,
var attachments = (from a in entities.Attachments
where a.AttachmentID == 749
select new {a.AddedOn, a.AddedBy});
这就产生了这个SQL,
SELECT
[Extent1].[AttachmentID] AS [AttachmentID],
[Extent1].[AddedOn] AS [AddedOn],
[Extent1].[AddedBy] AS [AddedBy]
FROM [dbo].[Attachment] AS [Extent1]
WHERE 749 = [Extent1].[AttachmentID]
这个没有子查询。
区别在于(至少其中一个)......等待它。 Informix的。上面生成子查询的第一个查询是使用informix。第二个查询不是SQL服务器。
它可能不那么简单,因为查询不同。
我确实接受了第二个查询并将其分解为像这样的子查询(手动),
SELECT
[Project1].[AttachmentID] AS [AttachmentID],
[Project1].[AddedOn] AS [AddedOn],
[Project1].[AddedBy] AS [AddedBy]
FROM ( SELECT
[Extent1].[AttachmentID] AS [AttachmentID],
[Extent1].[AddedOn] AS [AddedOn],
[Extent1].[AddedBy] AS [AddedBy]
FROM [dbo].[Attachment] AS [Extent1]
WHERE 749 = [Extent1].[AttachmentID]
) AS Project1
SQL服务器为两者显示相同的执行计划,因此您说SQL服务器能够非常好地优化它。另一方面,Informix在优化方面是阴暗的。
答案 0 :(得分:7)
它是否使用子查询生成SQL可能取决于您使用的实体框架提供程序。但由于大多数现有的谱系可能具有相同的谱系(因为它们可能是从Microsoft代码示例开始的),因此它们可能都会产生类似的SQL。提供者将获得一个查询树,该查询树由Linq语句生成,并负责生成SQL。执行此操作的过程是访问查询树中的节点并按原样生成SQL。
在OP的给定投影中,生成子查询是有意义的。它要求一组值(new ... {StartMetres,EndMetres})取自前面的“查询”。因此,查询生成将生成"SELECT <requested values> FROM something"
,其中"something"
本身作为查询呈现。因此,查询树的简单访问会产生子查询。
完成该过程后,提供程序肯定可以“优化”生成的SQL并删除子查询。但是,这是SQL查询引擎真正擅长的事情,因此将该任务委派给查询引擎是有意义的。它可能取决于您使用的数据库,但是带有子查询的SQL语句的查询计划可能与没有子查询的“优化”查询计划相同。