Mit der folgenden Tabelle Struktur (Fremd Spalten entfernt) verbindeneinschließen und wo Prädikat Ursache kommt links statt inneren
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
)
Ich verwende die folgenden Linq-to-Entities-Abfragen:
// 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();
Produziert (aus einem SQL Profiler):
-- 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%')
Warum in der dritten Abfrage, generiert es ein LEFT OUTER JOIN
auf der Events
Tabelle ein zweites Mal? Während die Abfrage korrekte Ergebnisse produziert, scheint es seltsam, warum EF/LINQ nicht wieder verwenden [Extent2]
in SELECT
und WHERE
Klausel, und warum ist es ein LEFT OUTER JOIN
?
Ich verwende Visual Studio 2010 SP1 .NET 4 und verbinde mich mit Sql Server 2008 Express.
Die zweite Abfrage verwendet 'Include' und erzeugt noch keinen linken Join. – Matthew
Sehr gute Frage, das habe ich nicht bemerkt. Das scheint mir von vorne zu sein. Die zweite Abfrage sollte einen linken Join enthalten, damit Include keine Nebenwirkungen verursacht und die dritte Abfrage einen inneren Join aufweist, da sie ohnehin eine Ereigniszeile benötigt. – MikeKulls
Ein linker Join würde Sinn ergeben, wenn es sich um eine Spalte mit Nullwert handeln könnte oder wenn ich keine referenzielle Integrität darauf hätte. – Matthew