Mat*_*hew 8 c# linq linq-to-entities entity-framework
使用以下表结构(删除了无关的列)
create table [Events]
(
ID int not null identity,
Name nvarchar(128) not null,
constraint PK_Events primary key(ID)
)
create table [Donations]
(
ID int not null identity,
EventID int not null,
Amount decimal(10, 2) not null,
constraint PK_Donations primary key(ID),
constraint FK_Donations_Events foreign key(EventID) references [Events](ID) on update no action on delete no action
)
Run Code Online (Sandbox Code Playgroud)
我使用以下Linq-to-Entities查询:
// 1
ents.Donations.Where(d => d.Amount > 25.0m && d.Event.Name.Contains("Run")).ToList();
// 2
ents.Donations.Include("Event").Where(d => d.Amount > 25.0m).ToList();
// 3
ents.Donations.Include("Event").Where(d => d.Amount > 25.0m && d.Event.Name.Contains("Run")).ToList();
Run Code Online (Sandbox Code Playgroud)
生成(来自SQL事件探查器):
-- 1
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[EventID] AS [EventID],
[Extent1].[Amount] AS [Amount]
FROM [dbo].[Donations] AS [Extent1]
INNER JOIN [dbo].[Events] AS [Extent2] ON [Extent1].[EventID] = [Extent2].[ID]
WHERE ([Extent1].[Amount] > 25.0) AND ([Extent2].[Name] LIKE N'%Run%')
-- 2
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[EventID] AS [EventID],
[Extent1].[Amount] AS [Amount],
[Extent2].[ID] AS [ID1],
[Extent2].[Name] AS [Name]
FROM [dbo].[Donations] AS [Extent1]
INNER JOIN [dbo].[Events] AS [Extent2] ON [Extent1].[EventID] = [Extent2].[ID]
WHERE [Extent1].[Amount] > 25.0
-- 3
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[EventID] AS [EventID],
[Extent1].[Amount] AS [Amount],
[Extent3].[ID] AS [ID1],
[Extent3].[Name] AS [Name]
FROM [dbo].[Donations] AS [Extent1]
INNER JOIN [dbo].[Events] AS [Extent2] ON [Extent1].[EventID] = [Extent2].[ID]
LEFT OUTER JOIN [dbo].[Events] AS [Extent3] ON [Extent1].[EventID] = [Extent3].[ID]
WHERE ([Extent1].[Amount] > 25.0) AND ([Extent2].[Name] LIKE N'%Run%')
Run Code Online (Sandbox Code Playgroud)
为什么在第3次查询中,它是否第二次LEFT OUTER JOIN
在Events
桌面上生成?虽然查询产生了正确的结果,但看起来很奇怪,为什么EF/LINQ不能[Extent2]
在SELECT
和WHERE
子句中重复使用,为什么它是一个LEFT OUTER JOIN
?
我正在使用Visual Studio 2010 sp1 .NET 4,我正在连接到Sql Server 2008 Express.
左边的连接是为了确保在捐赠指向不存在的事件的情况下Donations表中没有丢失任何行.他们不希望Include关键字具有导致原始表中缺少行的副作用,因此他们必须使用左连接以确保安全.
关于将表包括两次,这可能只是EF的限制.您在查询中提到了两次,并且进行优化并不够智能.
我不得不说,如果你想优化SQL然后编写SQL,不要打扰EF.您正在做的事情可以与反编译C#进行比较,并询问汇编程序为什么没有某种优化.如果你使用EF然后关闭它产生的SQL :-)
归档时间: |
|
查看次数: |
3355 次 |
最近记录: |